def register_object(reg_node=None, attr_name=None, obj=None, log=False): '''Register an object to a reg_node Attributes: reg_node -- Registration node. pm.nt.Transform attr_name -- Name for attr to be created on reg_node. Str obj -- Object to connect message attr to reg_node.attr. pm.nt.Transform ''' general.check_type(reg_node, 'reg_node', [pm.nt.Transform]) general.check_type(attr_name, 'attr_name', [str]) general.check_type(obj, 'obj', [pm.nt.Transform]) for attr in ['version', 'reg_node']: if not hasattr(reg_node, attr): raise errors.ObjectError(reg_node, 'Attr: %s' % attr, None) reg_node.addAttr(attr_name, at='message') pm.connectAttr('%s.message' % obj, '%s.%s' % (reg_node, attr_name), f=1) if log: str_1 = 'Connected: %s.%s >> %s.message' % (reg_node, attr_name, obj) general.logging.debug(str_1)
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 patch_spaceswitch_dpspine_objects(): """ This function is not clean, but it can be used to generate spaceswitch object for certain module and after look at all space switch target information to replace to space switch object target that could used a ctrl to the new space switch object that will not be removed after an unbuild """ # Get the rig instance in the scene (Now support only the first one found rig_net = libSerialization.get_networks_from_class('Rig')[0] rig_instance = libSerialization.import_network(rig_net) # Get all the module that we could need to patch to_patch = [module for module in rig_instance.modules if isinstance(module, rigDpSpine.DpSpine)] for module in to_patch: module_to_patch = module if isinstance(module_to_patch, rigDpSpine.DpSpine): # Find all connection that have from the ctrl ik down (COG) and replace it connected_to_fk_dwn = module_to_patch.ctrl_fk_dwn._network.message.outputs(s=False, d=True, p=True) for connection in connected_to_fk_dwn: attr_name = connection.shortName() if attr_name.find('targets') >= 0: log.info('Reconnecting {0} from {1} to space switch node {2}' .format(connection, module_to_patch.ctrl_ik_dwn, module_to_patch.ctrl_ik_dwn._network)) connection.disconnect() pymel.connectAttr(module_to_patch.ctrl_ik_dwn._network.message, connection, force=True)
def create_dominant_color_shader(dag, tex_name_surfix=['co', 'color', 'diffuse', 'dif', 'base'], sample_rate=None, max_auto_sample=50, default_shader='aiStandardSurface', default_channel='baseColor'): """ Create an auto average-color lambert shader and assign it to input object. Maybe does not work with TIFF texture ( cannot extract color ). """ if type(dag) == pm.nodetypes.Transform: mesh = dag.getShape() if not type(mesh) == pm.nodetypes.Mesh: return None elif type(dag) == pm.nodetypes.Mesh: mesh = dag else: return None avg_color = _detect_dominant_color(mesh, tex_name_surfix, sample_rate, max_auto_sample, default_shader, default_channel) if not avg_color: return None color_shader, sg = pm.createSurfaceShader('lambert') color_shader.color.set(avg_color) pm.connectAttr(color_shader.color, sg.surfaceShader, f=1) pm.sets(sg, forceElement=mesh) return color_shader
def stretchyBack( ikHandleTorso, jntList ): pymelLogger.debug('Starting: stretchyBack()...') #Stretchy process # ArcLen to create curveInfo curveInfoNodeBack = pm.arclen( ikHandleTorso[2], ch=True ) # add attr to curveinfo Node (normalizedScale) # this will have a value coming from a multiply divide node that will be # dividing the current length by the initial length of the curve # this will be used later to scale the joints pm.addAttr(curveInfoNodeBack, longName='normalizedScale', attributeType='double') # get initial length of the curve iniLen = pm.getAttr( curveInfoNodeBack + '.arcLength' ) # create a node multiplydivide, operation set to division MDCurveBack = pm.shadingNode( 'multiplyDivide', asUtility=True ) pm.setAttr( MDCurveBack+'.operation', 2 ) # divide # Connect curve arcLength to input1X pm.connectAttr( curveInfoNodeBack + '.arcLength', MDCurveBack + '.input1X', force=True ) # Set input2X to initial length of the curve pm.setAttr(MDCurveBack+'.input2X', iniLen) # connect outpux x from multiplydivide to normalized scale of the curve info pm.connectAttr(MDCurveBack + '.outputX', curveInfoNodeBack + '.normalizedScale', force=True) returnList = [curveInfoNodeBack,MDCurveBack] pymelLogger.debug('End: stretchyBack()...') return returnList
def addSegment(self, segment): ''' expects an instance of Ocd_Segment passed as 'segmemnt' ''' p = pmc.FabricCanvasInstPreset(m=self.cn.getName(), e='', p='Fabric.Core.Array.Push', x=len(self.pushes)*300+100, y=len(self.pushes)*100+100) # Create input port and connections port = pmc.FabricCanvasAddPort(m=self.cn.getName(), e='', d=segment.name, p='In', ui=opaqueDict, t='Vec3[]') pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s=port, d='%s.element' % p) pmc.connectAttr('%s.result' % segment.name, '%s.%s' % (self.cn.getName(), port)) pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s='%s.array' % p, d='%s.positions' % self.chain) if self.pushes: pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s='%s.array' % self.pushes[-1], d='%s.array' % p) self.pushes.append(p) self.segments.append(segment) # Create localMat for new joint # This allows a non-straight joint to be initialized with a zero value. # When bend is calculated, this local offset is applied to the space in which the bend is computed. p = pmc.FabricCanvasInstPreset(m=self.cn.getName(), e='', p='Fabric.Core.Array.Push', x=len(self.initMatPushes)*300+300, y=len(self.initMatPushes)*100+300) m = pmc.FabricCanvasInstPreset(m=self.cn.getName(), e='', p='Fabric.Exts.Math.Constants.Mat44', x=len(self.initMatPushes)*300+100, y=len(self.initMatPushes)*100+300) pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s='%s.value' % m, d='%s.element' % p) pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s='%s.array' % p, d='%s.initMats' % self.chain) if self.initMatPushes: pmc.FabricCanvasConnect(m=self.cn.getName(), e='', s='%s.array' % self.initMatPushes[-1], d='%s.array' % p) self.initMatPushes.append(p) self.initMats.append(m)
def createBoundJointConstraintsAndConnectVisibility(self): pm.select(cl = True) #bound joint constraint list self.boundJointConstraintList = [] #iterate bound joint list and create orient constraint for each for index in range(len(self.boundJointsList)): pm.select(cl = True) self.boundJointConstraintList.append(pm.orientConstraint(self.ikSplineJointsList[index], self.ikDynamicJointsList[index], self.boundJointsList[index], mo = True)) pm.select(cl = True) #create reverse node self.orientConstraintWeight_reverse = pm.createNode('reverse') pm.select(cl = True) #connect to manip dynamic blend self.manip_dynamic.manualDynamicBlend >> self.orientConstraintWeight_reverse.inputX pm.select(cl = True) #Connect Constraints to manip_dynamic for index in range(len(self.boundJointConstraintList)): pm.select(cl = True) pm.connectAttr(self.orientConstraintWeight_reverse.outputX, self.boundJointConstraintList[index].name() +'.' +self.ikSplineJointsList[index].name() +'W0', f = True) pm.connectAttr(self.manip_dynamic.manualDynamicBlend, self.boundJointConstraintList[index].name() +'.' +self.ikDynamicJointsList[index].name() +'W1', f = True) pm.select(cl = True) #Visibility self.orientConstraintWeight_reverse.outputX >> self.manipIkSplineTopGrp.visibility
def build(self): super(CurveDeformer, self).build() oCurve = next((o for o in self.input if any (s for s in o.getShapes() if isinstance(s, pymel.nodetypes.NurbsCurve))), None) oSurface = next((o for o in self.input if any (s for s in o.getShapes() if isinstance(s, pymel.nodetypes.NurbsSurface))), None) if self.type == self.kType_NurbsSurface: oSurface = _createNurbsSurfaceFromNurbsCurve(oCurve) oSurface.rename(self._pNameMapRig.Serialize()+'_nurbsSurface') oSurface.setParent(self.grp_rig) for i in range(oSurface.numKnotsInV()-1): cluster, clusterHandle = pymel.cluster(oSurface.cv[0:3][i]) cluster.rename(self._pNameMapRig.Serialize('cluster', _iIter=i)) clusterHandle.rename(self._pNameMapRig.Serialize('clusterHandle', _iIter=i)) clusterHandle.setParent(self.grp_rig) uRef = pymel.createNode('transform') uRef.rename(self._pNameMapRig.Serialize('cvRef', _iIter=i)) uRef.setParent(self.grp_rig) pymel.connectAttr(oCurve.controlPoints[i], uRef.t) #pymel.connectAttr(libRigging.CreateUtilityNode('pointOnCurveInfo', inputCurve=oCurve.worldSpace, parameter=((float(i)/(oSurface.numKnotsInV()-3)))).position, uRef.t) #pymel.tangentConstraint(oCurve, uRef) clusterHandle.setParent(uRef) assert(isinstance(oSurface, pymel.PyNode)) self.aJnts = _createSurfaceJnts(oSurface, self.numJnts) for i, jnt in enumerate(self.aJnts): jnt.rename(self._pNameMapRig.Serialize(_iIter=i)) jnt.setParent(self.grp_rig)
def addAOV( aovName, aovType = None ): """docstring for addAov""" if aovType is None: aovType = aovs.getAOVTypeMap().get(aovName, 'rgba') if not isinstance(aovType, int): aovType = dict(aovs.TYPES)[aovType] aovNode = pm.createNode('aiAOV', name='aiAOV_' + aovName, skipSelect=True) out = aovNode.attr('outputs')[0] pm.connectAttr('defaultArnoldDriver.message', out.driver) filter = aovs.defaultFiltersByName.get(aovName, None) if filter: node = pm.createNode('aiAOVFilter', skipSelect=True) node.aiTranslator.set(filter) filterAttr = node.attr('message') import mtoa.hooks as hooks hooks.setupFilter(filter, aovName) else: filterAttr = 'defaultArnoldFilter.message' pm.connectAttr(filterAttr, out.filter) aovNode.attr('name').set(aovName) aovNode.attr('type').set(aovType) base = pm.PyNode('defaultArnoldRenderOptions') aovAttr = base.aovs nextPlug = aovAttr.elementByLogicalIndex(aovAttr.numElements()) aovNode.message.connect(nextPlug) aov = aovs.SceneAOV(aovNode, nextPlug) return aov
def swap_mesh(self, new_mesh, calibrate=True): """ Change the mesh that the follicle is attached to. This is made to be used on a build InteractiveCtrlModel. :param new_mesh: A pymel.nodetypes.Mesh or pymel.nodetypes.Transform containing a mesh. """ # Resolve the node driven by the follicle. # This node contain the bindPose of the ctrl and is linked via a parentConstraint which we'll want to re-create. # todo: how do we update the constraint again? constraint = next( obj for obj in self.follicle.translate.outputs() if isinstance(obj, pymel.nodetypes.ParentConstraint)) target = constraint.getParent() pymel.delete(constraint) pos = target.getTranslation(space='world') # Get the new uv coordinates and apply them _, new_u, new_v = libRigging.get_closest_point_on_mesh(new_mesh, pos) pymel.connectAttr(new_mesh.outMesh, self.follicle.inputMesh, force=True) self.follicle.attr('parameterU').set(new_u) self.follicle.attr('parameterV').set(new_v) # Recreate the constraint pymel.parentConstraint(self.follicle, target, maintainOffset=True) if calibrate: self.calibrate()
def fetch_attr(self, source, target): if source is None: return elif isinstance(source, pymel.Attribute): pymel.connectAttr(source, target) else: target.set(source)
def jointsOnCurve(crv=None, num=None, name=None): if not crv: return if not num: return if not name: return if num < 1: return param_increment = 1.0/float(num) param = 0 curveShape = pm.PyNode(crv).getShape() prnt = [] for i in range(num): pm.select(clear=1) # Create joint jnt = pm.joint(n=name+'_'+str(i).zfill(2)) # Attach to curve poci = pm.createNode('pointOnCurveInfo') pm.connectAttr('%s.ws'%curveShape,'%s.inputCurve'%poci,f=1) pm.connectAttr('%s.position'%poci,'%s.translate'%jnt,f=1) pm.setAttr('%s.parameter'%poci,param) pm.setAttr('%s.turnOnPercentage'%poci,1) pm.disconnectAttr('%s.position'%poci,'%s.translate'%jnt) pm.delete(poci) if len(prnt): pm.parent(jnt,prnt[-1]) prnt.append(jnt) param += param_increment
def Connect(src, dst): pm.undoInfo(openChunk=True) alembics = src if not isinstance(src, list): alembics = pm.ls(src, dagObjects=True, type='transform') targets = dst if not isinstance(dst, list): targets = pm.ls(dst, dagObjects=True, type='transform') attrs = ['translate', 'rotate', 'scale', 'visibility'] for node in targets: for abc in alembics: if node.longName().split(':')[-1] == abc.longName().split(':')[-1]: for attr in attrs: pm.connectAttr('%s.%s' % (abc, attr), '%s.%s' % (node, attr), force=True) # securing primary shape is connected pm.connectAttr('%s.worldMesh[0]' % abc.getShape(), '%s.inMesh' % node.getShape(), force=True) pm.undoInfo(closeChunk=True)
def FTV_multiConnectAutoKeyableNonLocked(src, dest, attsExcept): '''connect every keyable and non locked attribute of src to dest (basically connect parameters from control)''' atts = pm.listAttr(src, k=True, u=True) for a in atts: if a in attsExcept: continue pm.connectAttr(src+'.'+a, dest+'.'+a)
def addAOV(self, aovName, aovType=None): ''' add an AOV to the active list for this AOV node returns the created AOV node ''' if aovType is None: aovType = getAOVTypeMap().get(aovName, 'rgba') if not isinstance(aovType, int): aovType = dict(TYPES)[aovType] aovNode = pm.createNode('aiAOV', name='aiAOV_' + aovName, skipSelect=True) out = aovNode.attr('outputs')[0] pm.connectAttr('defaultArnoldDriver.message', out.driver) filter = defaultFiltersByName.get(aovName, None) if filter: node = pm.createNode('aiAOVFilter', skipSelect=True) node.aiTranslator.set(filter) filterAttr = node.attr('message') import mtoa.hooks as hooks hooks.setupFilter(filter, aovName) else: filterAttr = 'defaultArnoldFilter.message' pm.connectAttr(filterAttr, out.filter) aovNode.attr('name').set(aovName) aovNode.attr('type').set(aovType) nextPlug = self.nextAvailableAttr() aovNode.message.connect(nextPlug) aov = SceneAOV(aovNode, nextPlug) addAliases([aov]) return aov
def rigConnectAttrsFromChannelbox( ): attrs = getAttrsFromChannelbox() num = len(attrs)/2 for a,b in zip( attrs[num:], attrs[:num] ): pm.connectAttr( a, b ) print a, '-->', b
def CreateFKControl(self, _joint, _parent, _moduleContainer): jointName = utils.StripAllNamespaces(_joint)[1] containedNodes = [] name = "%s_fkControl" %jointName controlObjectInstance = controlObject.ControlObject() fkControlInfo = controlObjectInstance.Create(name, "sphere.ma", self, _lod = 1, _translation = False, _rotation = True, _globalScale = False, _spaceSwitching = False) fkControl = fkControlInfo[0] pm.connectAttr("%s.rotateOrder" %_joint, "%s.rotateOrder" %fkControl) orientGrp = pm.group(name = "%s_orientGrp", empty = True, parent = _parent) containedNodes.append(orientGrp) pm.delete(pm.parentConstraint(_joint, orientGrp, maintainOffset = False)) jointParent = pm.listRelatives(_joint, parent = True)[0] orientGrp_parentConstraint = pm.parentConstraint(jointParent, orientGrp, maintainOffset = True, name = "%s_parentConstraint" %orientGrp) orientGrp_scaleConstraint = pm.scaleConstraint(jointParent, orientGrp, maintainOffset = True, name = "%s_scaleConstraint" %orientGrp) pm.parent(fkControl, orientGrp, relative = True) orientConstraint = pm.orientConstraint(fkControl, _joint, maintainOffset = False, name = "%s_orientConstraint" %_joint) containedNodes.extend([orientGrp_parentConstraint, orientGrp_scaleConstraint, orientConstraint]) utils.AddNodeToContainer(_moduleContainer, containedNodes) return fkControl
def assignToSelected(self, layerIndex, channelIndex): for obj in pm.selected(): materialChannelList = [".diffuse", ".diffuse_weight", ".transparency", ".reflectivity", ".refl_gloss", ".cutout_opacity", ".bump", ".normal"] shapeNode = pm.listRelatives(obj, c=True, s=True) shadingGrp = pm.listConnections(shapeNode, type="shadingEngine")[0] mat = list(set( pm.listConnections(shadingGrp, type=['mia_material_x', 'mia_material_x_passes', 'lambert', 'phong'])))[ 0] try: currentItem = self.layeredTextureTreeModel.itemFromIndex(layerIndex[0]).node except: pm.cmds.warning("Please select a texture from the list.") try: if channelIndex < 6: outAttr = ".outColor" if channelIndex != 0: outAttr = ".outAlpha" currentItemOutColor = currentItem + outAttr materialInput = mat + materialChannelList[channelIndex] pm.connectAttr(currentItemOutColor, materialInput, f=True) elif channelIndex == 6: createBump(currentItem, mat) else: createBump(currentItem, mat, normal=True) except: pm.cmds.warning("Could not connect materials to " + obj)
def connect(self): # Connect internal influence to network attr_out = self._get_attr_out_world_tm() pymel.connectAttr(self.obj.worldMatrix, attr_out) # Connect network to external influence _connect_matrix_to_trs(attr_out, self.obj_external)
def importAbcFile(): importFilePath=pm.textField('path_ABC2', q=True, text=True) #.abc를 없애준다 filePathDeletAbc = importFilePath.replace('.abc','') pm.importFile( filePathDeletAbc+'.ma' ) importAbc( filePathDeletAbc+'.abc' ) connectionsTxtFile_open = open(filePathDeletAbc+'.txt') import pickle lst = pickle.load(connectionsTxtFile_open) print lst for geo, shd, aiShd,disShd in lst: cmds.select( geo ) cmds.hyperShade( assign=shd ) node=pm.ls(geo)[0] shape = node.getShape() shadingGrps = shape.outputs( type='shadingEngine' ) print shadingGrps[0] shader=pm.ls(aiShd)[0] print shader try: print 'good' pm.connectAttr(shader.outColor,shadingGrps[0].aiSurfaceShader) except: print 'false' try: disShader=pm.ls(disShd)[0] pm.connectAttr(disShader.outColor,shadingGrps[0]..displacementShader) except: print 'no dis'
def _get_follicle_absolute_uv_attr(self, mult_u=1.0, mult_v=1.0): """ Resolve the absolute parameterU and parameterV that will be sent to the follicles. :param mult_u: Custom multiplier :param mult_v: :return: A tuple containing two pymel.Attribute: the absolute parameterU and relative parameterV. """ # TODO: Move attribute definition outside this function. attr_u_inn = libAttr.addAttr(self.grp_rig, longName=self._ATTR_NAME_U) attr_v_inn = libAttr.addAttr(self.grp_rig, longName=self._ATTR_NAME_V) attr_u_relative, attr_v_relative = self._get_follicle_relative_uv_attr(mult_u=mult_u, mult_v=mult_v) # Add base parameterU & parameterV attr_u_cur = libRigging.create_utility_node( 'addDoubleLinear', input1=self._attr_u_base, input2=attr_u_relative ).output attr_v_cur = libRigging.create_utility_node( 'addDoubleLinear', input1=self._attr_v_base, input2=attr_v_relative ).output # TODO: Move attribute connection outside of this function. pymel.connectAttr(attr_u_cur, attr_u_inn) pymel.connectAttr(attr_v_cur, attr_v_inn) return attr_u_inn, attr_v_inn
def createJoints(self, name=None, curve=None, num=None): ''' Create groups on curve. ''' num = float(num) joints = [] param_increment = 1.0/num param = 0 curveshape = curve.getShape() prnt = [] for i in range(int(num)): pm.select(clear=1) # create joint jnt = pm.joint(name='%s%s_jnt' % (name, i)) joints.append(jnt) # attach to curve poci = pm.createNode('pointOnCurveInfo') pm.connectAttr('%s.ws' % curveshape, '%s.inputCurve' % poci, f=1) pm.connectAttr('%s.position' % poci, '%s.translate' % jnt, f=1) pm.setAttr('%s.turnOnPercentage' % poci, 1) pm.setAttr('%s.parameter' % poci, param) pm.disconnectAttr('%s.position' % poci, '%s.translate' % jnt) pm.delete(poci) if len(prnt): pm.parent(jnt, prnt[-1]) prnt.append(jnt) param += param_increment return joints
def connect_or_set_attr(_attr, _val): if isinstance(_val, list) or isinstance(_val, tuple): # Note: List attribute and compound attribute don't have the same way of iterating. if _attr.isArray(): for i, val in enumerate(_val): connect_or_set_attr(_attr.elementByLogicalIndex(i), val) elif _attr.isCompound(): children = _attr.getChildren() for child, val in zip(children, _val): connect_or_set_attr(child, val) else: raise Exception("Can't apply value {0} on attribute {1}, need an array or compound".format(_val, _attr)) ''' for i, pSubValue in enumerate(_val): ConnectOrSetAttr(_attr.elementByLogicalIndex(i), pSubValue) ''' else: if isinstance(_val, pymel.Attribute): pymel.connectAttr(_val, _attr, force=True) elif is_basic_type(_val): _attr.set(_val) else: logging.error( '[ConnectOrSetAttr] Invalid value for attribute {0} of type {1} and value {2}'.format(_attr.name(), type(_val), _val)) raise TypeError
def create_render_cam(name="RENDER_CAM", exposure=True): """ Creates a camera and renames it str name: name of the camera bool exposure: connect a mia_exposure_photographic node to the camera """ if not pm.objExists(name): cam = pm.camera()[0] pm.rename(cam, name) [cam.renderable.set(cam.name().startswith(name)) for cam in pm.ls(cameras=True)] cam = pm.PyNode(name) if exposure: if not cam.miLensShader.isConnected(): node = pm.createNode("mia_exposure_photographic") node.film_iso.set(800) node.f_number.set(1.2) node.gamma.set(1) pm.connectAttr(node.message, cam.miLensShader, force=True) cam.getShape().setDisplayResolution(True) pm.lookThru(name) pm.select(cam)
def connectAttr_withLinearDrivenKeys(attr_src, attr_dst, type='animCurveUU', force=True, kt=(-1.0,0.0,1.0), kv=(-1.0,0.0,1.0), kit=(4,2,4), kot=(4,2,4), pre='linear', pst='linear'): # Skip if a connection already exist for node in getAttrOutput(attr_src, plugs=False, skipBlendWeighted=True): if 'animCurveU' in node.type(): drivenkey_outplugs = getAttrOutput(node.output, plugs=True, skipBlendWeighted=True) for drivenkey_outplug in drivenkey_outplugs: if drivenkey_outplug == attr_dst: if force: pymel.disconnectAttr(node.input) pymel.disconnectAttr(node.output) pymel.delete(node) else: print("Can't connect. Attribute {0} is already connected to {1} via {2}".format( attr_src.longName(), attr_dst.longName(), drivenkey_outplug.node().longName() )) return animCurve = create_animCurveU('animCurveUU', kt=kt, kv=kv, kit=kit, # Spline/Linear/Spline kot=kot, # Spline/Linear/Spline pre=pre, pst=pst ) animCurve.rename('{0}_{1}'.format(attr_src.node().name(), attr_src.longName())) pymel.connectAttr(attr_src, animCurve.input) return connectAttr_withBlendWeighted(animCurve.output, attr_dst)
def createSubdivApproxNode(): ''' copy of createApproxNode from mentalrayApproxEditor.mel node will be named "mathildaSubdivApprox" ''' # delete existing node if exists nodeName = 'mathildaSubdivApprox' # make sure mental ray is loaded first if not pm.pluginInfo('Mayatomr', q=True, loaded=True): pm.loadPlugin('Mayatomr', qt=True) # create approx node approxNode = pm.createNode('mentalraySubdivApprox', n=nodeName) # get listNode try: mrItemsListNode = pm.ls(type='mentalrayItemsList')[0] except IndexError: mrItemsListNode = pm.createNode('mentalrayItemsList', n='mentalrayItemsList') # connect approx to list pm.connectAttr(approxNode.message, mrItemsListNode.subdivApproxs, na=True) return approxNode
def create_compound_ctrl(self, cls, inst, suffix, attr_inn_name, attr_out_name, **kwargs): """ Initialize and build and connect a controller used in the Compound. :param cls: The desired class for the controller. :param inst: The current instance. :param suffix: A str that identify this controller. :param attr_inn_name: The name of the network attribute that receive the controller local matrix. :param attr_out_name: The name of the network attribute that will drive the controller offset world matrix. :param kwargs: Any keyword argument will be passed to the controller .build() method. :return: A controller instance of the desired type. """ attr_inn = self.grp_inn.attr(attr_inn_name) attr_out = self.grp_out.attr(attr_out_name) nomenclature_anm = self.get_nomenclature_anm() inst = self.init_ctrl(cls, inst) ref_tm = attr_out.get() inst.build( name=nomenclature_anm.resolve(suffix), geometries=self.rig.get_meshes(), refs=[ref_tm], **kwargs ) inst.setParent(self.grp_anm) pymel.connectAttr(inst.matrix, attr_inn) _connect_matrix_attr_to_transform(attr_out, inst.offset) return inst
def main(): prefRun() center = pm.ikHandle(name="centerIK", startJoint="center1", endEffector="center13", sol="ikSplineSolver",ns=3) left = pm.ikHandle(name="leftIK", startJoint="left1", endEffector="left13", sol="ikSplineSolver",ns=3) right = pm.ikHandle(name="rightIK", startJoint="right1", endEffector="right13", sol="ikSplineSolver",ns=3) pm.rename(center[2], "center_crv") pm.rename(left[2], "left_crv") pm.rename(right[2], "right_crv") clusterGrp_center = clusterCurve("center_crv") clusterGrp_left = clusterCurve("left_crv") clusterGrp_right = clusterCurve("right_crv") pm.connectAttr("jacketRight1.rz", clusterGrp_right+".rz") pm.connectAttr("jacketLeft1.rz", clusterGrp_left+".rz") pm.parent("center_crv", "rig") pm.parent("left_crv", "rig") pm.parent("right_crv", "rig") pm.parent(clusterGrp_center, "world_ctrl") pm.parent(clusterGrp_left, "world_ctrl") pm.parent(clusterGrp_right, "world_ctrl") for i in ["centerIK", "leftIK", "rightIK"]: pm.setAttr(i+".visibility", 0) pm.parent(i, "rig") for i in ['center_crv','left_crv','right_crv','center_crv_cv0_loc', 'left_crv_cv0_loc', 'right_crv_cv0_loc', 'pageTargets_grp', 'pages_grp', 'jacket_grp']: pm.setAttr(i+".visibility", 0)
def create_ibl(* args): ''' # creates an ibl ''' my_ibl = pm.shadingNode('mentalrayIblShape', asLight= True) pm.connectAttr('%s.message' % (my_ibl), 'mentalrayGlobals.imageBasedLighting', force= True) pm.setAttr('%s.primaryVisibility' % (my_ibl), 1) pm.setAttr('%s.visibleInReflections' % (my_ibl), 1) pm.setAttr('%s.visibleInRefractions' % (my_ibl), 1) pm.setAttr('%s.visibleInEnvironment' % (my_ibl), 1) pm.setAttr('%s.visibleInFinalGather' % (my_ibl), 1) scene_objects = pm.ls(type= ['mesh', 'nurbsSurface', 'volumeLight', 'spotLight', 'directionalLight','areaLight', 'pointLight', 'ambientLight']) bounding_box = pm.exactWorldBoundingBox(scene_objects) bounding_box.sort() ibl_size = bounding_box[-1] pm.setAttr('%s.scaleX' % (my_ibl), ibl_size) pm.setAttr('%s.scaleY' % (my_ibl), ibl_size) pm.setAttr('%s.scaleZ' % (my_ibl), ibl_size) return my_ibl
def build(self, refs=None, line_target=True, *args, **kwargs): """ Will create the ctrl node and it's line target if needed :param refs: The reference used to attach the line target :param line_target: Bool to tell if we want a line target :param args: More args passed to the super class :param kwargs: More kwargs passed to the super class :return: """ super(CtrlIkSwivel, self).build(*args, **kwargs) assert (self.node is not None) ref = next(iter(refs), None) if isinstance(refs, collections.Iterable) else refs # Create line if line_target is True and ref is not None: # Create a spaceLocator so the annotation can hook itself to it. self._line_locator = pymel.spaceLocator() locator_shape = self._line_locator.getShape() pymel.pointConstraint(ref, self._line_locator) self._line_locator.setParent(self.node) self._line_locator.hide() self._line_annotation = pymel.createNode('annotationShape') annotation_transform = self._line_annotation.getParent() self._line_annotation.setParent(self.node, relative=True, shape=True) pymel.connectAttr(locator_shape.worldMatrix, self._line_annotation.dagObjectMatrix[0], force=True) pymel.delete(annotation_transform) return self.node
def facialLocalWorldControllers(module, parent, ctrlSize=1): ctrlSizeHalf = [ctrlSize / 2.0, ctrlSize / 2.0, ctrlSize / 2.0] ctrlSizeQuarter = [ctrlSize / 4.0, ctrlSize / 4.0, ctrlSize / 4.0] ctrlSize = [ctrlSize, ctrlSize, ctrlSize] transLocs = cmds.ls("*_sdk2_LOC", type="transform") for loc in transLocs: locName = loc.replace('_sdk2', '') side = rig_nameGetSide(locName) base = locName #if side: base = rig_nameGetBase(locName) print 'side = ' + side print 'base = ' + base name = loc.replace('_sdk2_LOC', '') print 'name = ' + name localOffset = rig_transform(0, name=name + 'LocalOffset', parent=module.parts, target=loc).object localCon = rig_transform(0, name=name + 'LocalCon', parent=localOffset, target=localOffset).object pm.parentConstraint(loc, localCon, mo=True) ctrlName = base + 'Twk' if 'Tweak' in base: ctrlName = base.replace('Tweak', 'Twker') print 'ctrlName = ' + ctrlName ctrl = rig_control(side=side, name=ctrlName, shape='circle', modify=1, scale=ctrlSize, directCon=1, parentOffset=module.controlsSec, secColour=1, directConAttrs=('tx', 'ty', 'tz', 'rx', 'ry', 'rz')) pm.rotate(ctrl.ctrl.cv, 0, 0, 90, r=True, os=True) if side == 'r': pm.move(ctrl.ctrl.cv, -0.2, 0, 0, r=True, os=True) else: pm.move(ctrl.ctrl.cv, 0.2, 0, 0, r=True, os=True) jnt = pm.listRelatives(loc, type='joint', c=True)[0] pm.delete(pm.parentConstraint(loc, ctrl.offset)) pm.parent(ctrl.offset, parent) for at in ('tx', 'ty', 'tz', 'rx', 'ry', 'rz'): pm.connectAttr(localCon + '.' + at, ctrl.modify + '.' + at) pm.connectAttr(ctrl.ctrl + '.' + at, jnt + '.' + at)
## Book Set Up ## import pymel.core as pm import tak_misc reload(tak_misc) # Page bulgeClsts = [] selLs = pm.ls(sl=True) for sel in selLs: pm.select(sel, r=True) ffdNodes = pm.lattice(sel, divisions=[2,5,2], objectCentered=True, ldv=[2,2,2], n=sel+"_ffd") ffdNodes[0].setAttr("local", 0) clst = pm.cluster("%s.pt[0:1][1][0]" %(ffdNodes[1]), "%s.pt[0:1][1][1]" %(ffdNodes[1]), n=sel+"_ffd_clst") pm.addAttr(sel.split("_")[0]+"_ctrl", ln="bulge", at="float", keyable=True) pm.connectAttr(sel.split("_")[0]+"_ctrl"+".bulge", clst[0]+"Handle.translateX") # Page1~5 selLs = pm.ls(sl=True) for sel in selLs: pm.select(sel, r=True) ffdNodes = pm.lattice(sel, divisions=[2,5,2], objectCentered=True, ldv=[2,2,2], n=sel+"_ffd") ffdNodes[0].setAttr("local", 0) clst = pm.cluster("%s.pt[0:1][1][0]" %(ffdNodes[1]), "%s.pt[0:1][1][1]" %(ffdNodes[1]), n=sel+"_ffd_clst") pm.addAttr(sel.rsplit("_", 1)[0] + "_ctrl", ln="bulge", at="float", keyable=True) pm.connectAttr(sel.rsplit("_", 1)[0]+"_ctrl"+".bulge", clst[0]+"Handle.translateX") groupName = sel.split("_", 1)[0] + "_bulge_system_grp" if groupName: pm.parent(ffdNodes[1:], clst[1], groupName)
def connect_fresnel(self, file_node, slot_name): file_node.alphaIsLuminance.set(True) pm.connectAttr(file_node.outAlpha, '%s.%s' % (self.shader, slot_name))
def connect_color_texture(self, file_node, slot_name): pm.connectAttr(file_node.outColor, '%s.%s' % (self.shader, slot_name))
def gear_rollsplinekine_op(out, controlers=[], u=.5, subdiv=10): """Apply a sn_rollsplinekine_op operator Arguments: out (dagNode): onstrained Object. controlers (list of dagNodes): Objects that will act as controler of the bezier curve. Objects must have a parent that will be used as an input for the operator. u (float): Position of the object on the bezier curve (from 0 to 1). subdiv (int): spline subdivision precision. Returns: pyNode: The newly created operator. """ node = pm.createNode("mgear_rollSplineKine") # Inputs pm.setAttr(node + ".u", u) pm.setAttr(node + ".subdiv", subdiv) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", out + ".translate") pm.connectAttr(dm_node + ".outputRotate", out + ".rotate") # connectAttr(dm_node+".outputScale", out+".scale") pm.connectAttr(out + ".parentMatrix", node + ".outputParent") for i, obj in enumerate(controlers): pm.connectAttr(obj + ".parentMatrix", node + ".ctlParent[%s]" % i) pm.connectAttr(obj + ".worldMatrix", node + ".inputs[%s]" % i) pm.connectAttr(obj + ".rx", node + ".inputsRoll[%s]" % i) return node
def gear_ikfk2bone_op(out=[], root=None, eff=None, upv=None, fk0=None, fk1=None, fk2=None, lengthA=5, lengthB=3, negate=False, blend=0): """Apply a sn_ikfk2bone_op operator Arguments: out (list of dagNodes): The constrained outputs order must be respected (BoneA, BoneB, Center, CenterN, Eff), set it to None if you don't want one of the output. root (dagNode): Object that will act as the root of the chain. eff (dagNode): Object that will act as the eff controler of the chain. upv (dagNode): Object that will act as the up vector of the chain. fk0 (dagNode): Object that will act as the first fk controler of the chain. fk1 (dagNode): Object that will act as the second fk controler of the chain. fk2 (dagNode): Object that will act as the fk effector controler of the chain. lengthA (float): Length of first bone. lengthB (float): Length of second bone. negate (bool): Use with negative Scale. blend (float): Default blend value (0 for full ik, 1 for full fk). Returns: pyNode: The newly created operator. """ node = pm.createNode("mgear_ikfk2Bone") # Inputs pm.setAttr(node + ".lengthA", lengthA) pm.setAttr(node + ".lengthB", lengthB) pm.setAttr(node + ".negate", negate) pm.setAttr(node + ".blend", blend) pm.connectAttr(root + ".worldMatrix", node + ".root") pm.connectAttr(eff + ".worldMatrix", node + ".ikref") pm.connectAttr(upv + ".worldMatrix", node + ".upv") pm.connectAttr(fk0 + ".worldMatrix", node + ".fk0") pm.connectAttr(fk1 + ".worldMatrix", node + ".fk1") pm.connectAttr(fk2 + ".worldMatrix", node + ".fk2") # Outputs if out[0] is not None: pm.connectAttr(out[0] + ".parentMatrix", node + ".inAparent") dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".outA", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", out[0] + ".translate") pm.connectAttr(dm_node + ".outputRotate", out[0] + ".rotate") pm.connectAttr(dm_node + ".outputScale", out[0] + ".scale") if out[1] is not None: pm.connectAttr(out[1] + ".parentMatrix", node + ".inBparent") dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".outB", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", out[1] + ".translate") pm.connectAttr(dm_node + ".outputRotate", out[1] + ".rotate") pm.connectAttr(dm_node + ".outputScale", out[1] + ".scale") if out[2] is not None: pm.connectAttr(out[2] + ".parentMatrix", node + ".inCenterparent") dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".outCenter", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", out[2] + ".translate") pm.connectAttr(dm_node + ".outputRotate", out[2] + ".rotate") # connectAttr(dm_node+".outputScale", out[2]+".scale") # the scaling # is not working with FK blended to 1. # The output is from the solver I need to review the c++ solver if out[3] is not None: pm.connectAttr(out[3] + ".parentMatrix", node + ".inEffparent") dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(node + ".outEff", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", out[3] + ".translate") pm.connectAttr(dm_node + ".outputRotate", out[3] + ".rotate") pm.connectAttr(dm_node + ".outputScale", out[3] + ".scale") return node
def gear_spring_op(in_obj, goal=False): """Apply mGear spring node. Arguments: in_obj (dagNode): Constrained object. goal (dagNode): By default is False. Returns: pyNode: Newly created node """ if not goal: goal = in_obj node = pm.createNode("mgear_springNode") pm.connectAttr("time1.outTime", node + ".time") dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(goal + ".parentMatrix", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", node + ".goal") cm_node = pm.createNode("composeMatrix") pm.connectAttr(node + ".output", cm_node + ".inputTranslate") mm_node = pm.createNode("mgear_mulMatrix") pm.connectAttr(cm_node + ".outputMatrix", mm_node + ".matrixA") pm.connectAttr(in_obj + ".parentInverseMatrix", mm_node + ".matrixB") dm_node2 = pm.createNode("decomposeMatrix") pm.connectAttr(mm_node + ".output", dm_node2 + ".inputMatrix") pm.connectAttr(dm_node2 + ".outputTranslate", in_obj + ".translate") pm.setAttr(node + ".stiffness", 0.5) pm.setAttr(node + ".damping", 0.5) return node
place2d_node.outUvFilterSize >> file_node.uvFilterSize place2d_node.repeatUV >> file_node.repeatUV place2d_node.rotateFrame >> file_node.rotateFrame place2d_node.rotateUV >> file_node.rotateUV place2d_node.stagger >> file_node.stagger place2d_node.translateFrame >> file_node.translateFrame place2d_node.vertexCameraOne >> file_node.vertexCameraOne place2d_node.vertexUvOne >> file_node.vertexUvOne place2d_node.vertexUvThree >> file_node.vertexUvThree place2d_node.vertexUvTwo >> file_node.vertexUvTwo place2d_node.wrapU >> file_node.wrapU place2d_node.wrapV >> file_node.wrapV pm.select(cl = True) #connect shader to shading group pm.connectAttr( shader_node.name() + ".outColor", shading_group_node.name() + ".surfaceShader", force = True) pm.select(cl = True) #connect file to ocio node file_node.outColor >> ocio_node.input_color pm.select(cl = True) #connect ocio node to shader ocio_node.output_color >> shader_node.outColor pm.select(cl = True) #set texture file file_node.fileTextureName.set(texture_dir +'/' +texture_name) #polyplane_transform_node, polyplane_shape_node polyplane_transform_node, polyplane_shape_node = pm.polyPlane(n = 'ocio_test_polyplane', sx = 10, sy = 10, axis = (0,1,0), width = 12.8, height = 7.8)
def load_to_maya(positions, names=None, parents=None, color=None, radius=0.1, thickness=5.0): import pymel.core as pm import maya.mel as mel if names is None: names = ['joint_%i' % i for i in xrange(positions.shape[1])] if color is None: color = (0.5, 0.5, 0.5) mpoints = [] frames = range(1, len(positions) + 1) for i, name in enumerate(names): #try: # point = pm.PyNode(name) #except pm.MayaNodeError: # point = pm.sphere(p=(0,0,0), n=name, radius=radius)[0] point = pm.sphere(p=(0, 0, 0), n=name, radius=radius)[0] jpositions = positions[:, i] for j, attr, attr_name in zip( xrange(3), [point.tx, point.ty, point.tz], ["_translateX", "_translateY", "_translateZ"]): conn = attr.listConnections() if len(conn) == 0: curve = pm.nodetypes.AnimCurveTU(n=name + attr_name) pm.connectAttr(curve.output, attr) else: curve = conn[0] curve.addKeys(frames, jpositions[:, j]) mpoints.append(point) if parents != None: for i, p in enumerate(parents): if p == -1: continue pointname = names[i] parntname = names[p] conn = pm.PyNode(pointname).t.listConnections() if len(conn) != 0: continue curve = pm.curve(p=[[0, 0, 0], [0, 1, 0]], d=1, n=names[i] + '_curve') pm.connectAttr(pointname + '.t', names[i] + '_curve.cv[0]') pm.connectAttr(parntname + '.t', names[i] + '_curve.cv[1]') pm.select(curve) pm.runtime.AttachBrushToCurves() stroke = pm.selected()[0] brush = pm.listConnections(stroke.getChildren()[0] + '.brush')[0] pm.setAttr(brush + '.color1', color) pm.setAttr(brush + '.globalScale', thickness) pm.setAttr(brush + '.endCaps', 1) pm.setAttr(brush + '.tubeSections', 20) mel.eval('doPaintEffectsToPoly(1,0,0,1,100000);') mpoints += [stroke, curve] return pm.group(mpoints, n='AnimationPositions'), mpoints
def makeUIConnections(self): """ Connects the facial UI to the blendShapes. Returns: """ print 'Making connections for the shapes to the UI...' bmNode = pm.PyNode('BM_nodes') if not bmNode.objExists(): pm.error('Missing %s, Please check and try again.' % bmNode) return False if not bmNode.guiimport.get(): facialFile = self.facialUI_cb.currentText() if not facialFile: pm.error('Please select a proper facial file.') return False facialFilePath = os.path.join(self.facialFileLocation, str(facialFile)).replace('\\', '/') pm.importFile(facialFilePath) bmNode.guiimport.set(1) # get blendshape list from the blendShapeNode. blendShapeNode = pm.PyNode('%s_blendShapeNode' % self.baseMeshShapeNode) shapeList = pm.listAttr(blendShapeNode + '*.w', m=1, k=1) # Now read the config and make the connections... configFile = self.facialConfig_cb.currentText().replace('.py', '') importStatement = "pcgiShapeManager.config.%s" % configFile baseConfig = importlib.import_module(importStatement) reload(baseConfig) mainController = pm.PyNode('face_facial_ctl') usedShapes = list() for key, val in baseConfig.facialConnectionsDict.iteritems(): if val: # shapeToConnect = None for eachShape in shapeList: if val in eachShape: usedShapes.append(eachShape) pm.connectAttr( '%s.%s' % (str(mainController), key), '%s.%s' % (self.blendShapeNode, eachShape)) extraShapes = set(shapeList) - set(usedShapes) for eachExtraShape in extraShapes: if 'pupil' in eachExtraShape: ret = blendShapeUtils.decompileNames( eachExtraShape, str(self.mainfileter_le.text())) pm.connectAttr('face_r_pupil_fac_ctl.%s' % (ret['#shape']), '%s.%s' % (self.blendShapeNode, eachExtraShape)) else: attrName = '_'.join(eachExtraShape.split('_')[-2:]) extraShapeCtl = pm.PyNode('face_extrashapes_fac_ctl') extraShapeCtl.addAttr(attrName, at='float', min=0, max=1, dv=0, k=1) pm.connectAttr('%s.%s' % (extraShapeCtl, attrName), '%s.%s' % (self.blendShapeNode, eachExtraShape))
def __init__(self, ikHandle, ikCtrl, doFlexyplane=True): ikHandle = pm.ls(ikHandle)[0] ikCtrl = pm.ls(ikCtrl)[0] prefix = name.removeSuffix(ikHandle.name()) jointList = pm.ikHandle(ikHandle, jointList=True, q=True) endJoint = pm.listRelatives(jointList[-1], c=True, type='joint')[0] jointList.append(endJoint) distanceDimensionShape = pm.distanceDimension( sp=jointList[0].getTranslation(space='world'), ep=jointList[-1].getTranslation(space='world')) locators = pm.listConnections(distanceDimensionShape, s=True) startLoc = pm.rename(locators[0], prefix + 'DistanceStart_LOC') endLoc = pm.rename(locators[1], prefix + 'DistanceEnd_LOC') pm.pointConstraint(jointList[0], startLoc) pm.pointConstraint(ikCtrl, endLoc) # multiplyDivide Node multiplyDivideNode = pm.shadingNode('multiplyDivide', asUtility=True, n=prefix + '_multiplyDivide') multiplyDivideNode.input2X.set(1) multiplyDivideNode.operation.set(2) pm.connectAttr(distanceDimensionShape.distance, multiplyDivideNode.input1X, f=True) distance = 0 for i in range(0, len(jointList[:-1])): distance = distance + util.get_distance(jointList[i], jointList[i + 1]) multiplyDivideNode.input2X.set(distance) # condition Node conditionNode = pm.shadingNode('condition', asUtility=True, n=prefix + '_condition') conditionNode.operation.set(2) pm.connectAttr(distanceDimensionShape.distance, conditionNode.firstTerm, f=True) pm.connectAttr(multiplyDivideNode.input2X, conditionNode.secondTerm, f=True) pm.connectAttr(multiplyDivideNode.outputX, conditionNode.colorIfTrueR, f=True) for jnt in jointList[:-1]: pm.connectAttr(conditionNode.outColorR, jnt.scaleX, f=True) self.stretchyGrp = pm.group(startLoc, endLoc, distanceDimensionShape.getParent(), n=prefix + 'Stretchy_GRP') self.stretchyGrp.visibility.set(0) # save attributes self.prefix = prefix self.jointList = jointList if doFlexyplane: self.doFlexyPlane(prefix)
'face_A_fac_ctl', 'face_r_brow_wor_fac_ctl', 'face_l_brow_wor_fac_ctl', 'face_r_half_eye_squint_fac_ctl', 'face_l_upper_eyelid_fac_ctl', 'face_Smileright_fac_ctl', 'face_l_lower_eyelid_fac_ctl', 'face_r_sneerup_fac_ctl', 'face_CDGK_fac_ctl', 'face_l_brow_agr_fac_ctl', 'face_l_brow_sad_fac_ctl', 'face_l_sneerup_fac_ctl', 'face_U_fac_ctl', 'face_l_sneerdown_fac_ctl', 'face_lwr_teeth_clench_fac_ctl', 'face_upr_teeth_clench_fac_ctl', 'face_l_cheek_puff_fac_ctl', 'face_mouthopen_fac_ctl', 'face_Smile1_fac_ctl', 'face_Smile2_fac_ctl', 'face_r_cheek_puff_fac_ctl' ] for eachConnection in directConnections: connectionName = (eachConnection.replace('face_', '')).replace('_fac_ctl', '') mainController.addAttr(connectionName, at='double', min=0, max=1, dv=1) pm.connectAttr('%s.ty' % eachConnection, '%s.%s' % (mainController, connectionName)) biDirectionConectionsY = [ 'face_l_eyesquint_fac_ctl', 'face_r_eyesquint_fac_ctl', 'face_l_brow_fac_ctl', 'face_r_brow_fac_ctl', 'face_jaw_fac_ctl', 'face_mouth_slide_fac_ctl', 'face_r_cnr_fac_ctl', 'face_l_cnr_fac_ctl' ] directionalList = [('Y', 0, 1), ('Y', 0, 0), ('X', 1, 1), ('X', 1, 0)] yPlus = 1 yMin = 1 xPlus = 0 xMin = 0 for idx, each in enumerate(['yPlus', 'yMin']): # , xPlus, xMin]): for eachConnection in biDirectionConectionsY:
def genMat(*args): selected = pm.ls(sl=1, long=1) matName = 'master_attr_mat' proxyName = 'proxy_attr_mat' existAttrMat = pm.ls((matName), materials=True) masterMat = False if (len(existAttrMat) == 0): rn1 = rand.uniform(0, 1) rn2 = rand.uniform(0, 1) rn3 = rand.uniform(0, 1) # create master material andol 5 masterMat = pm.shadingNode('aiStandardSurface', name=matName, asShader=True) pm.setAttr((masterMat + '.baseColor'), randCol(), type='double3') proxyMat = pm.shadingNode('lambert', name=proxyName, asShader=True) #create vrtx col hook and boolean diffVrtx = pm.shadingNode('aiUserDataColor', name='diffVrtxAttr', asTexture=True) pm.setAttr((diffVrtx + '.colorAttrName'), 'colorSet1', type='string') pm.setAttr((diffVrtx + '.defaultValue'), (rand.uniform(0, 1)), (rand.uniform(0, 1)), (rand.uniform(0, 1)), type='double3') # create diff col attr diffCol = pm.shadingNode('aiUserDataColor', name='diffColAttr', asTexture=True) pm.setAttr((diffCol + '.colorAttrName'), 'diffCol', type='string') pm.setAttr((diffCol + '.defaultValue'), (rand.uniform(0, 1)), (rand.uniform(0, 1)), (rand.uniform(0, 1)), type='double3') # bool attribute for vrtx diff diffVrtxBool = pm.shadingNode('aiUserDataBool', name='diffVrtxBool', asUtility=True) pm.setAttr((diffVrtxBool + '.boolAttrName'), 'diffVrtxTog', type='string') pm.setAttr((diffVrtxBool + '.defaultValue'), False) # switch between diff col and dif vrtx diffColSwitch = pm.shadingNode('colorCondition', name='useDiffVrtx', asUtility=True) pm.connectAttr((diffVrtx + '.outColor'), (diffColSwitch + '.colorA')) pm.connectAttr((diffVrtx + '.outTransparencyR'), (diffColSwitch + '.alphaA')) pm.connectAttr((diffCol + '.outColor'), (diffColSwitch + '.colorB')) pm.connectAttr((diffCol + '.outTransparencyR'), (diffColSwitch + '.alphaB')) pm.connectAttr((diffVrtxBool + '.outValue'), (diffColSwitch + '.condition')) #create difftex attribute and empty texture file and udim attr diffTexStr = pm.shadingNode('aiUserDataString', name='diffTexAttr', asUtility=True) pm.setAttr((diffTexStr + '.stringAttrName'), 'diffTex', type='string') # diff tex udim diffUdimBool = pm.shadingNode('aiUserDataBool', name='diffUdimBool', asUtility=True) pm.setAttr((diffUdimBool + '.boolAttrName'), 'diffUdim', type='string') pm.setAttr((diffUdimBool + '.defaultValue'), False) #diff file diffTexFile = pm.shadingNode('file', name='diffTexFile', asTexture=True) pm.connectAttr((diffTexStr + '.outValue'), (diffTexFile + '.fileTextureName')) #diff file udimm diffTexFileUdim = pm.shadingNode('file', name='diffTexFileUdim', asTexture=True) pm.setAttr((diffTexFileUdim + '.uvTilingMode'), 3) pm.connectAttr((diffTexStr + '.outValue'), (diffTexFileUdim + '.fileTextureName')) #switch between tex and udim tex diffTexUdimSwitch = pm.shadingNode('colorCondition', name='useDiffUdimTex', asUtility=True) pm.connectAttr((diffTexFile + '.outColor'), (diffTexUdimSwitch + '.colorA')) pm.connectAttr((diffTexFile + '.outAlpha'), (diffTexUdimSwitch + '.alphaA')) pm.connectAttr((diffTexFileUdim + '.outColor'), (diffTexUdimSwitch + '.colorB')) pm.connectAttr((diffTexFileUdim + '.outAlpha'), (diffTexUdimSwitch + '.alphaB')) pm.connectAttr((diffUdimBool + '.outValue'), (diffTexUdimSwitch + '.condition')) # bool for diff tex diffTexBool = pm.shadingNode('aiUserDataBool', name='diffTexBool', asUtility=True) pm.setAttr((diffTexBool + '.boolAttrName'), 'diffTexTog', type='string') pm.setAttr((diffTexBool + '.defaultValue'), False) # switch between diff atr branch and dif file diffTexSwitch = pm.shadingNode('colorCondition', name='useDiffTex', asUtility=True) pm.connectAttr((diffTexUdimSwitch + '.outColor'), (diffTexSwitch + '.colorA')) pm.connectAttr((diffTexUdimSwitch + '.outAlpha'), (diffTexSwitch + '.alphaA')) pm.connectAttr((diffColSwitch + '.outColor'), (diffTexSwitch + '.colorB')) pm.connectAttr((diffColSwitch + '.outAlpha'), (diffTexSwitch + '.alphaB')) pm.connectAttr((diffTexBool + '.outValue'), (diffTexSwitch + '.condition')) pm.connectAttr((diffTexSwitch + '.outColor'), (masterMat + '.baseColor')) pm.connectAttr((diffTexSwitch + '.outAlpha'), (masterMat + '.opacityR')) pm.connectAttr((diffTexSwitch + '.outAlpha'), (masterMat + '.opacityG')) pm.connectAttr((diffTexSwitch + '.outAlpha'), (masterMat + '.opacityB')) pm.connectAttr((diffTexSwitch + '.outColor'), (proxyMat + '.color')) #pm.connectAttr((diffTexSwitch +'.outAlpha'), (proxyMat +'.transparencyR')) #pm.connectAttr((diffTexSwitch +'.outAlpha'), (proxyMat +'.transparencyG')) #pm.connectAttr((diffTexSwitch +'.outAlpha'), (proxyMat +'.transparencyB')) masterMatShadingGroup = pm.shadingNode('shadingEngine', name=(masterMat + '_SG'), asShader=True) #addMember pm.connectAttr((proxyMat + '.outColor'), (masterMatShadingGroup + '.surfaceShader')) pm.connectAttr((masterMat + '.outColor'), (masterMatShadingGroup + '.aiSurfaceShader')) else: masterMat = existAttrMat[0] for member in selected: pm.select(member) pm.hyperShade(member, assign=masterMat) pm.select(selected)
def rotations_load_to_maya(rotations, positions, names=None): """ Load Rotations into Maya Loads a Quaternions array into the scene via the representation of axis Parameters ---------- rotations : (F, J) Quaternions array of rotations to load into the scene where F = number of frames J = number of joints positions : (F, J, 3) ndarray array of positions to load rotation axis at where: F = number of frames J = number of joints names : [str] List of joint names Returns ------- maxies : Group Grouped Maya Node of all Axis nodes """ import pymel.core as pm if names is None: names = ["joint_" + str(i) for i in range(rotations.shape[1])] maxis = [] frames = range(1, len(positions) + 1) for i, name in enumerate(names): name = name + "_axis" axis = pm.group(pm.curve(p=[(0, 0, 0), (1, 0, 0)], d=1, n=name + '_axis_x'), pm.curve(p=[(0, 0, 0), (0, 1, 0)], d=1, n=name + '_axis_y'), pm.curve(p=[(0, 0, 0), (0, 0, 1)], d=1, n=name + '_axis_z'), n=name) axis.rotatePivot.set((0, 0, 0)) axis.scalePivot.set((0, 0, 0)) axis.childAtIndex(0).overrideEnabled.set(1) axis.childAtIndex(0).overrideColor.set(13) axis.childAtIndex(1).overrideEnabled.set(1) axis.childAtIndex(1).overrideColor.set(14) axis.childAtIndex(2).overrideEnabled.set(1) axis.childAtIndex(2).overrideColor.set(15) curvex = pm.nodetypes.AnimCurveTA(n=name + "_rotateX") curvey = pm.nodetypes.AnimCurveTA(n=name + "_rotateY") curvez = pm.nodetypes.AnimCurveTA(n=name + "_rotateZ") arotations = rotations[:, i].euler() curvex.addKeys(frames, arotations[:, 0]) curvey.addKeys(frames, arotations[:, 1]) curvez.addKeys(frames, arotations[:, 2]) pm.connectAttr(curvex.output, axis.rotateX) pm.connectAttr(curvey.output, axis.rotateY) pm.connectAttr(curvez.output, axis.rotateZ) offsetx = pm.nodetypes.AnimCurveTU(n=name + "_translateX") offsety = pm.nodetypes.AnimCurveTU(n=name + "_translateY") offsetz = pm.nodetypes.AnimCurveTU(n=name + "_translateZ") offsetx.addKeys(frames, positions[:, i, 0]) offsety.addKeys(frames, positions[:, i, 1]) offsetz.addKeys(frames, positions[:, i, 2]) pm.connectAttr(offsetx.output, axis.translateX) pm.connectAttr(offsety.output, axis.translateY) pm.connectAttr(offsetz.output, axis.translateZ) maxis.append(axis) return pm.group(*maxis, n='RotationAnimation')
pm.connectAttr(ctrlAttrA,'%s.input1D[0]'%pmaNode,f=1) if scaleB: scaleB_node = pm.shadingNode('multiplyDivide',n='%s_ScaleB'%sumCtrl, asUtility=1) pm.setAttr('%s.input1X'%scaleB_node,scaleB) pm.connectAttr(ctrlAttrB,'%s.input2X'%scaleB_node,f=1) pm.connectAttr('%s.outputX'%scaleB_node,'%s.input1D[1]'%pmaNode,f=1) else: pm.connectAttr(ctrlAttrB,'%s.input1D[1]'%pmaNode,f=1) try: pm.addAttr(sumCtrl, ln=ctrlAttrResult.split('.')[1], k=1) except Exception, e: raise( e ) pm.connectAttr('%s.output1D'%pmaNode, ctrlAttrResult, f=1) sumCtrl = 'FaceGui' cntrl = 'JawSyncDistLoc' attrA = 'JawSyncDistA.distance' attrB = 'JawSyncDistB.distance' sumAttrName = 'JawSync_L_Wide_Sum' sumAttr(sumCtrl=sumCtrl, ctrlAttrA='%s' % (attrA), ctrlAttrB='%s' % (attrB), ctrlAttrResult='%s.%s' % (sumCtrl, sumAttrName), scaleA=None, scaleB=None) #------------------------------------ # Give BS's and controls, create attributes that drive each blendshape on control. import pymel.core as pm
def add_target(self, aNewParent, firstSetup=False): """ Add a new target to the space switch system """ iNbTgt = len(self.nSwConst.getWeightAliasList()) aExistTgt = self.nSwConst.getTargetList() for nParent in aNewParent: #Ensure that the parent doesn't already exist in the drivers list if not nParent in aExistTgt: #First, calculate the offset between the parent and the driven node vTrans = self._get_tm_offset(nParent, type="t") vRot = self._get_tm_offset(nParent, type="r") #Connect the new target manually in the parent constraint if (iNbTgt == 0): self.nSwConst.addAttr(nParent.name() + "W" + str(iNbTgt), at="double", min=0, max=1, dv=1, k=True, h=False) else: self.nSwConst.addAttr(nParent.name() + "W" + str(iNbTgt), at="double", min=0, max=1, dv=0, k=True, h=False) pymel.connectAttr( nParent.parentMatrix, self.nSwConst.target[iNbTgt].targetParentMatrix) pymel.connectAttr(nParent.scale, self.nSwConst.target[iNbTgt].targetScale) pymel.connectAttr( nParent.rotateOrder, self.nSwConst.target[iNbTgt].targetRotateOrder) pymel.connectAttr(nParent.rotate, self.nSwConst.target[iNbTgt].targetRotate) pymel.connectAttr( nParent.rotatePivotTranslate, self.nSwConst.target[iNbTgt].targetRotateTranslate) pymel.connectAttr( nParent.rotatePivot, self.nSwConst.target[iNbTgt].targetRotatePivot) pymel.connectAttr(nParent.translate, self.nSwConst.target[iNbTgt].targetTranslate) #Link the created attributes to the weight value of the target nConstTgtWeight = pymel.Attribute(self.nSwConst.name() + "." + nParent.name() + "W" + str(iNbTgt)) pymel.connectAttr(nConstTgtWeight, self.nSwConst.target[iNbTgt].targetWeight) #Set the offset information self.nSwConst.target[ iNbTgt].targetOffsetTranslate.targetOffsetTranslateX.set( vTrans[0]) self.nSwConst.target[ iNbTgt].targetOffsetTranslate.targetOffsetTranslateY.set( vTrans[1]) self.nSwConst.target[ iNbTgt].targetOffsetTranslate.targetOffsetTranslateZ.set( vTrans[2]) self.nSwConst.target[ iNbTgt].targetOffsetRotate.targetOffsetRotateX.set(vRot[0]) self.nSwConst.target[ iNbTgt].targetOffsetRotate.targetOffsetRotateY.set(vRot[1]) self.nSwConst.target[ iNbTgt].targetOffsetRotate.targetOffsetRotateZ.set(vRot[2]) pymel.setKeyframe(nConstTgtWeight, t=0, ott="step") pymel.setKeyframe( self.nSwConst.target[iNbTgt].targetOffsetTranslate, t=0, ott="step") pymel.setKeyframe( self.nSwConst.target[iNbTgt].targetOffsetRotate, t=0, ott="step") self.aDrivers.append(nParent) self.aDriversSubName.append(nParent.name()) iNbTgt += 1 else: print("Warning: " + nParent.name() + " is already a driver for " + self.nDriven)
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ dm_node_scl = node.createDecomposeMatrixNode(self.root.worldMatrix) if self.settings["keepLength"]: arclen_node = pm.arclen(self.mst_crv, ch=True) alAttr = pm.getAttr(arclen_node + ".arcLength") pm.addAttr(self.mst_crv, ln="length_ratio", k=True, w=True) node.createDivNode(arclen_node.arcLength, alAttr, self.mst_crv.length_ratio) div_node_scl = node.createDivNode(self.mst_crv.length_ratio, dm_node_scl.outputScaleX) step = 1.000 / (self.def_number - 1) u = 0.000 for i in range(self.def_number): cnsUpv = applyop.pathCns(self.upv_cns[i], self.upv_crv, cnsType=False, u=u, tangent=False) cns = applyop.pathCns(self.div_cns[i], self.mst_crv, False, u, True) # Connectiong the scale for scaling compensation for axis, AX in zip("xyz", "XYZ"): pm.connectAttr(dm_node_scl.attr("outputScale{}".format(AX)), self.div_cns[i].attr("s{}".format(axis))) if self.settings["keepLength"]: div_node2 = node.createDivNode(u, div_node_scl.outputX) cond_node = node.createConditionNode(div_node2.input1X, div_node2.outputX, 4, div_node2.input1X, div_node2.outputX) pm.connectAttr(cond_node + ".outColorR", cnsUpv + ".uValue") pm.connectAttr(cond_node + ".outColorR", cns + ".uValue") cns.setAttr("worldUpType", 1) cns.setAttr("frontAxis", 0) cns.setAttr("upAxis", 1) pm.connectAttr(self.upv_cns[i].attr("worldMatrix[0]"), cns.attr("worldUpMatrix")) u += step if self.settings["keepLength"]: # add the safty distance offset self.tweakTip_npo.attr("tx").set(self.off_dist) # connect vis line ref for shp in self.line_ref.getShapes(): pm.connectAttr(self.ikVis_att, shp.attr("visibility")) for ctl in self.tweak_ctl: for shp in ctl.getShapes(): pm.connectAttr(self.ikVis_att, shp.attr("visibility")) for ctl in self.fk_ctl: for shp in ctl.getShapes(): pm.connectAttr(self.fkVis_att, shp.attr("visibility"))
def sumAttr(sumCtrl=None, ctrlAttrA=None, ctrlAttrB=None, ctrlAttrResult=None, scaleA=None, scaleB=None): pmaNode = pm.shadingNode('plusMinusAverage',n='%s_Sum'%sumCtrl, asUtility=1) if scaleA: scaleA_node = pm.shadingNode('multiplyDivide',n='%s_ScaleA'%sumCtrl, asUtility=1) pm.setAttr('%s.input1X'%scaleA_node,scaleA) pm.connectAttr(ctrlAttrA,'%s.input2X'%scaleA_node,f=1) pm.connectAttr('%s.outputX'%scaleA_node,'%s.input1D[0]'%pmaNode,f=1) else: pm.connectAttr(ctrlAttrA,'%s.input1D[0]'%pmaNode,f=1) if scaleB: scaleB_node = pm.shadingNode('multiplyDivide',n='%s_ScaleB'%sumCtrl, asUtility=1) pm.setAttr('%s.input1X'%scaleB_node,scaleB) pm.connectAttr(ctrlAttrB,'%s.input2X'%scaleB_node,f=1) pm.connectAttr('%s.outputX'%scaleB_node,'%s.input1D[1]'%pmaNode,f=1) else: pm.connectAttr(ctrlAttrB,'%s.input1D[1]'%pmaNode,f=1) try: pm.addAttr(sumCtrl, ln=ctrlAttrResult.split('.')[1], k=1) except Exception, e: raise( e )
def addOperators(self): if self.settings["ikSolver"]: self.ikSolver = "ikRPsolver" else: pm.mel.eval("ikSpringSolver;") self.ikSolver = "ikSpringSolver" # 1 bone chain Upv ref ===================================================================================== self.ikHandleUpvRef = pri.addIkHandle(self.root, self.getName("ikHandleLegChainUpvRef"), self.legChainUpvRef, "ikSCsolver") pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) pm.parentConstraint( self.legChainUpvRef[0], self.upv_cns, mo=True) # mid joints ===================================================================================== for xjnt, midJ in zip(self.legBones[1:3], [self.mid1_jnt, self.mid2_jnt]): nod.createPairBlend(None, xjnt, .5, 1, midJ) pm.connectAttr(xjnt+".translate", midJ+".translate", f=True) pm.parentConstraint(self.mid1_jnt, self.knee_lvl) pm.parentConstraint(self.mid2_jnt, self.ankle_lvl) #joint length multiply multJnt1_node = nod.createMulNode(self.boneALenght_attr, self.boneALenghtMult_attr) multJnt2_node = nod.createMulNode(self.boneBLenght_attr, self.boneBLenghtMult_attr) multJnt3_node = nod.createMulNode(self.boneCLenght_attr, self.boneCLenghtMult_attr) # # IK 3 bones ====================================================================================================== self.ikHandle = pri.addIkHandle(self.softblendLoc, self.getName("ik3BonesHandle"), self.chain3bones, self.ikSolver, self.upv_ctl) # TwistTest if [round(elem, 4) for elem in tra.getTranslation(self.chain3bones[1])] != [round(elem, 4) for elem in self.guide.apos[1]]: add_nodeTwist = nod.createAddNode(180.0, self.roll_att) pm.connectAttr(add_nodeTwist+".output", self.ikHandle.attr("twist")) else: pm.connectAttr(self.roll_att, self.ikHandle.attr("twist")) # stable spring solver doble rotation pm.pointConstraint(self.root_ctl, self.chain3bones[0]) # softIK 3 bones operators aop.aimCns(self.aim_tra, self.ik_ref, axis="zx", wupType=4, wupVector=[1,0,0], wupObject=self.root_ctl, maintainOffset=False) plusTotalLength_node = nod.createPlusMinusAverage1D([multJnt1_node.attr("outputX"), multJnt2_node.attr("outputX"), multJnt3_node.attr("outputX")]) subtract1_node = nod.createPlusMinusAverage1D([plusTotalLength_node.attr("output1D"), self.soft_attr],2) distance1_node = nod.createDistNode(self.ik_ref, self.aim_tra) div1_node = nod.createDivNode(1.0, self.rig.global_ctl+".sx") mult1_node = nod.createMulNode(distance1_node+".distance", div1_node+".outputX") subtract2_node = nod.createPlusMinusAverage1D([mult1_node.attr("outputX"), subtract1_node.attr("output1D")],2) div2_node = nod.createDivNode(subtract2_node+".output1D", self.soft_attr) mult2_node = nod.createMulNode(-1, div2_node+".outputX") power_node = nod.createPowNode( self.softSpeed_attr, mult2_node+".outputX") mult3_node = nod.createMulNode(self.soft_attr, power_node+".outputX") subtract3_node = nod.createPlusMinusAverage1D([plusTotalLength_node.attr("output1D"), mult3_node.attr("outputX")],2) cond1_node = nod.createConditionNode(self.soft_attr, 0, 2,subtract3_node+".output1D", plusTotalLength_node+".output1D") cond2_node = nod.createConditionNode(mult1_node+".outputX", subtract1_node+".output1D", 2,cond1_node+".outColorR", mult1_node+".outputX") pm.connectAttr(cond2_node+".outColorR", self.wristSoftIK+".tz") #soft blend pc_node = pm.pointConstraint( self.wristSoftIK, self.ik_ref, self.softblendLoc) nod.createReverseNode(self.stretch_attr, pc_node+".target[0].targetWeight") pm.connectAttr(self.stretch_attr, pc_node+".target[1].targetWeight", f=True) #Stretch distance2_node = nod.createDistNode(self.softblendLoc, self.wristSoftIK) mult4_node = nod.createMulNode(distance2_node+".distance", div1_node+".outputX") #bones for i, mulNode in enumerate([multJnt1_node, multJnt2_node, multJnt3_node]): div3_node = nod.createDivNode(mulNode+".outputX", plusTotalLength_node+".output1D") mult5_node = nod.createMulNode(mult4_node+".outputX", div3_node+".outputX") mult6_node = nod.createMulNode(self.stretch_attr, mult5_node+".outputX") plus1_node = nod.createPlusMinusAverage1D([mulNode.attr("outputX"), mult6_node.attr("outputX")],1, self.chain3bones[i+1]+".tx") # IK 2 bones ====================================================================================================== self.ikHandle2 = pri.addIkHandle(self.softblendLoc2, self.getName("ik2BonesHandle"), self.chain2bones, self.ikSolver, self.upv_ctl) pm.connectAttr(self.roll_att, self.ikHandle2.attr("twist")) # stable spring solver doble rotation pm.pointConstraint(self.root_ctl, self.chain2bones[0]) parentc_node = pm.parentConstraint( self.ik2b_ikCtl_ref, self.ik2b_bone_ref, self.ik2b_blend) reverse_node = nod.createReverseNode(self.fullIK_attr, parentc_node+".target[0].targetWeight") pm.connectAttr(self.fullIK_attr, parentc_node+".target[1].targetWeight", f=True) # softIK 2 bones operators aop.aimCns(self.aim_tra2, self.ik2b_ik_ref, axis="zx", wupType=4, wupVector=[1,0,0], wupObject=self.root_ctl, maintainOffset=False) plusTotalLength_node = nod.createPlusMinusAverage1D([multJnt1_node.attr("outputX"), multJnt2_node.attr("outputX")]) subtract1_node = nod.createPlusMinusAverage1D([plusTotalLength_node.attr("output1D"), self.soft_attr], 2) distance1_node = nod.createDistNode(self.ik2b_ik_ref, self.aim_tra2) div1_node = nod.createDivNode(1, self.rig.global_ctl+".sx") mult1_node = nod.createMulNode(distance1_node+".distance", div1_node+".outputX") subtract2_node = nod.createPlusMinusAverage1D([mult1_node.attr("outputX"), subtract1_node.attr("output1D")], 2) div2_node = nod.createDivNode(subtract2_node+".output1D", self.soft_attr) mult2_node = nod.createMulNode(-1, div2_node+".outputX") power_node = nod.createPowNode(self.softSpeed_attr, mult2_node+".outputX") mult3_node = nod.createMulNode(self.soft_attr, power_node+".outputX" ) subtract3_node = nod.createPlusMinusAverage1D([plusTotalLength_node.attr("output1D"),mult3_node.attr("outputX")], 2) cond1_node = nod.createConditionNode(self.soft_attr, 0, 2,subtract3_node+".output1D", plusTotalLength_node+".output1D") cond2_node = nod.createConditionNode(mult1_node+".outputX", subtract1_node+".output1D", 2,cond1_node+".outColorR", mult1_node+".outputX") pm.connectAttr(cond2_node+".outColorR", self.ankleSoftIK+".tz") #soft blend pc_node = pm.pointConstraint( self.ankleSoftIK, self.ik2b_ik_ref, self.softblendLoc2) nod.createReverseNode(self.stretch_attr, pc_node+".target[0].targetWeight") pm.connectAttr(self.stretch_attr, pc_node+".target[1].targetWeight", f=True) #Stretch distance2_node = nod.createDistNode(self.softblendLoc2, self.ankleSoftIK) mult4_node = nod.createMulNode(distance2_node+".distance", div1_node+".outputX") for i, mulNode in enumerate([multJnt1_node, multJnt2_node]): div3_node = nod.createDivNode(mulNode+".outputX", plusTotalLength_node+".output1D") mult5_node = nod.createMulNode(mult4_node+".outputX", div3_node+".outputX") mult6_node = nod.createMulNode(self.stretch_attr, mult5_node+".outputX") plus1_node = nod.createPlusMinusAverage1D([mulNode.attr("outputX"), mult6_node.attr("outputX")],1, self.chain2bones[i+1]+".tx") ### IK/FK connections for i, x in enumerate(self.fk_ctl): pm.parentConstraint( x, self.legBonesFK[i], mo=True) for i, x in enumerate([self.chain2bones[0],self.chain2bones[1]] ): pm.parentConstraint( x, self.legBonesIK[i], mo=True) pm.pointConstraint(self.ik2b_ik_ref, self.legBonesIK[2]) aop.aimCns(self.legBonesIK[2], self.roll_ctl, axis="xy", wupType=4, wupVector=[0,1,0], wupObject=self.legBonesIK[1], maintainOffset=False) pm.connectAttr( self.chain3bones[-1].attr("tx"), self.legBonesIK[-1].attr("tx")) # foot twist roll pm.orientConstraint(self.ik_ref, self.legBonesIK[-1], mo=True) multInvert_node = nod.createMulNode(-1, self.chain3bones[-1].attr("tx"), self.ik2b_ik_ref.attr("tx")) for i, x in enumerate(self.legBones): blend_node = nod.createPairBlend(self.legBonesFK[i], self.legBonesIK[i], self.blend_att, 1, x) # Twist references ---------------------------------------- self.ikhArmRef, self.tmpCrv = aop.splineIK(self.getName("legRollRef"), self.rollRef, parent=self.root, cParent=self.legBones[0] ) if self.negate: initRound = -.001 multVal = -1 else: initRound = .001 multVal = 1 multTangent_node = nod.createMulNode(self.roundnessKnee_att, multVal) add_node = nod.createAddNode(multTangent_node+".outputX", initRound) pm.connectAttr(add_node+".output", self.tws1_rot.attr("sx")) for x in ["translate", "rotate"]: pm.connectAttr(self.knee_ctl.attr(x), self.tws1_loc.attr(x)) multTangent_node = nod.createMulNode(self.roundnessAnkle_att, multVal) add_node = nod.createAddNode(multTangent_node+".outputX", initRound) pm.connectAttr(add_node+".output", self.tws2_rot.attr("sx")) # for x in ["translate"]: for x in ["translate", "rotate"]: pm.connectAttr(self.ankle_ctl.attr(x), self.tws2_loc.attr(x)) # Volume ------------------------------------------- distA_node = nod.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = nod.createDistNode(self.tws1_loc, self.tws2_loc) distC_node = nod.createDistNode(self.tws2_loc, self.tws3_loc) add_node = nod.createAddNode(distA_node+".distance", distB_node+".distance") add_node2 = nod.createAddNode(distC_node+".distance", add_node+".output") div_node = nod.createDivNode(add_node2+".output", self.root_ctl.attr("sx")) #comp scaling dm_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix")) div_node2 = nod.createDivNode(div_node+".outputX", dm_node+".outputScaleX") self.volDriver_att = div_node2+".outputX" # Flip Offset ---------------------------------------- pm.connectAttr(self.ankleFlipOffset_att, self.tws2_loc.attr("rz")) pm.connectAttr(self.kneeFlipOffset_att, self.tws1_loc.attr("rz")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): subdiv = False if i == len(self.div_cns)-1 or i == 0: subdiv = 45 else: subdiv = 45 if i < (self.settings["div0"]+1): perc = i*.333 / (self.settings["div0"]+1.0) elif i < (self.settings["div0"] + self.settings["div1"]+2): perc = i*.333 / (self.settings["div0"]+1.0) else: perc = .5 + (i-self.settings["div0"]-3.0)*.5 / (self.settings["div1"]+1.0) if i < (self.settings["div0"]+2): perc = i*.333 / (self.settings["div0"]+1.0) elif i < (self.settings["div0"] + self.settings["div1"]+3): perc = .333 + (i-self.settings["div0"]-1)*.333 / (self.settings["div1"]+1.0) else: perc = .666 + (i-self.settings["div1"]-self.settings["div0"]-2.0)*.333 / (self.settings["div2"]+1.0) # we neet to offset the ankle and knee point to force the bone orientation to the nex bone span if perc == .333: perc = .3338 elif perc == .666: perc = .6669 perc = max(.001, min(.999, perc)) # Roll if self.negate: node = aop.gear_rollsplinekine_op(div_cns, [self.tws3_rot, self.tws2_rot, self.tws1_rot, self.tws0_rot], 1-perc, subdiv) else: node = aop.gear_rollsplinekine_op(div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot, self.tws3_rot], perc, subdiv) pm.connectAttr(self.resample_att, node+".resample") pm.connectAttr(self.absolute_att, node+".absolute") # Squash n Stretch node = aop.gear_squashstretch2_op(div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, node+".blend") pm.connectAttr(self.volDriver_att, node+".driver") pm.connectAttr(self.st_att[i], node+".stretch") pm.connectAttr(self.sq_att[i], node+".squash") # Visibilities ------------------------------------- # fk fkvis_node = nod.createReverseNode(self.blend_att) for ctrl in self.fk_ctl: for shp in ctrl.getShapes(): pm.connectAttr(fkvis_node+".outputX", shp.attr("visibility")) # ik for ctrl in [self.ik_ctl, self.roll_ctl]: for shp in ctrl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # setup leg node scale compensate pm.connectAttr(self.rig.global_ctl+".scale", self.setup+".scale") return
def matrixConstrain(driver, driven, parent=None, translate=True, rotate=True, scale=False): driver = pm.ls(driver)[0] driven = pm.ls(driven)[0] if not parent: parent = driven.getParent() mulMatrix = pm.shadingNode('multMatrix', asUtility=True) decomposeMatrix = pm.shadingNode('decomposeMatrix', asUtility=True) pm.connectAttr(mulMatrix.matrixSum, decomposeMatrix.inputMatrix) pm.connectAttr(driver.worldMatrix[0], mulMatrix.matrixIn[0]) pm.connectAttr(parent.worldInverseMatrix[0], mulMatrix.matrixIn[1]) if translate: pm.connectAttr(decomposeMatrix.outputTranslate, driven.translate) if rotate: pm.connectAttr(decomposeMatrix.outputRotate, driven.rotate) if scale: pm.connectAttr(decomposeMatrix.outputScale, driven.scale)
def curveInfo(self, infoNode): self._curveInfo = infoNode pm.connectAttr(self.curveNode.worldSpace, infoNode.inputCurve)
def rig_joints_base(self): total_distance = self.bone_chain_lenght() self._model.start_point = pm.spaceLocator( name="StretchyIkHandleStartPoint") self.name_convention.rename_name_in_format(self.start_point, useName=True) self._model.end_point = pm.spaceLocator( name="StretchyIkHandleEndPoint") self.name_convention.rename_name_in_format(self.end_point, useName=True) self.start_point.setParent(self.rig_system.kinematics) self.end_point.setParent(self.rig_system.kinematics) if self.reset_joints: pm.parent(self.start_point, self.reset_joints) pm.parent(self.end_point, self.reset_joints) pm.pointConstraint(self.joints[0], self.start_point) pm.pointConstraint(self.ik_handle, self.end_point) distance_node = pm.shadingNode( "distanceBetween", asUtility=True, name="IKDistance" + self.name_convention.get_a_short_name(self.joints[-1])) self.name_convention.rename_based_on_base_name(self.joints[2], distance_node, name=distance_node) pm.connectAttr(self.start_point.worldPosition[0], distance_node.point1, f=True) pm.connectAttr(self.end_point.worldPosition[0], distance_node.point2, f=True) condition_node = pm.shadingNode( "condition", asUtility=True, name="IkCondition" + self.name_convention.get_a_short_name(self.joints[2])) condition_node = self.name_convention.rename_based_on_base_name( self.joints[2], condition_node, name=condition_node) pm.connectAttr(distance_node + ".distance", condition_node + ".colorIfFalseR", f=True) pm.connectAttr(distance_node + ".distance", condition_node + ".secondTerm", f=True) pm.setAttr(condition_node + ".operation", 3) pm.setAttr(condition_node + ".firstTerm", total_distance) pm.setAttr(condition_node + ".colorIfTrueR", total_distance) multiply_divide = pm.shadingNode( "multiplyDivide", asUtility=True, name="IKStretchMultiply" + self.name_convention.get_a_short_name(self.joints[2])) self.name_convention.rename_based_on_base_name(self.joints[2], multiply_divide, name=multiply_divide) pm.connectAttr(condition_node + ".outColorR", multiply_divide + ".input1X", f=True) pm.setAttr(multiply_divide + ".input2X", total_distance) pm.setAttr(multiply_divide + ".operation", 2) # self.rig_space_switch.AddNumericParameter(self.controls_dict['ikHandle'], Name="StretchyIK") pm.addAttr(self.ik_handle, ln="stretchyIK", at='float', min=0, max=10, k=True) ik_switch_divide = pm.shadingNode( "multiplyDivide", asUtility=True, name="IkSwitchDivide" + self.name_convention.get_a_short_name(self.joints[2])) self.name_convention.rename_based_on_base_name(self.joints[2], ik_switch_divide, name=ik_switch_divide) pm.connectAttr("%s.stretchyIK" % self.ik_handle, ik_switch_divide + ".input1X") pm.setAttr(ik_switch_divide + ".input2X", 10) pm.setAttr(ik_switch_divide + ".operation", 2) ik_switchblend_two_attr = pm.shadingNode( "blendTwoAttr", asUtility=True, name="IkSwitchBlendTwoAttr{}".format( self.name_convention.get_a_short_name(self.joints[2]))) self.name_convention.rename_based_on_base_name( self.joints[2], ik_switchblend_two_attr, name=ik_switchblend_two_attr) pm.connectAttr(multiply_divide.outputX, ik_switchblend_two_attr.input[1], force=True) ik_switchblend_two_attr.input[0].set(1) pm.connectAttr(ik_switch_divide.outputX, ik_switchblend_two_attr.attributesBlender, force=True) for joints in self.joints[:-1]: pm.connectAttr(ik_switchblend_two_attr.output, '{}.scaleX'.format(joints))
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # 1 bone chain Upv ref ============================================== self.ikHandleUpvRef = primitive.addIkHandle( self.root, self.getName("ikHandleArmChainUpvRef"), self.armChainUpvRef, "ikSCsolver", ) pm.pointConstraint(self.ik_ctl, self.ikHandleUpvRef) p_cns = pm.parentConstraint(self.armChainUpvRef[0], self.upv_cns, mo=True) p_cns.interpType.set(0) # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) try: for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node.outputX, shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node.outputX, shp.attr("visibility")) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis_node.outputX, shp.attr("visibility")) except RuntimeError: pm.displayInfo("Visibility already connected") # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.line_ref.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) if self.settings["ikTR"]: for shp in self.ikRot_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.roll_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.fk0_ctl, "XZY") attribute.setRotOrder(self.fk1_ctl, "XYZ") attribute.setRotOrder(self.fk2_ctl, "YZX") attribute.setRotOrder(self.ik_ctl, "XYZ") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_loc] o_node = applyop.gear_ikfk2bone_op( out, self.root, self.ik_ref, self.upv_ctl, self.fk_ctl[0], self.fk_ctl[1], self.fk_ref, self.length0, self.length1, self.negate, ) # NOTE: Ideally we should not change hierarchy or move object after # object generation method. But is much easier this way since every # part is in the final and correct position # after the ctrn_loc is in the correct position with the ikfk2bone op # point constrain tip reference pm.pointConstraint(self.ik_ctl, self.tip_ref, mo=False) # interpolate transform mid point locator int_matrix = applyop.gear_intmatrix_op( self.armChainUpvRef[0].attr("worldMatrix"), self.tip_ref.attr("worldMatrix"), 0.5, ) applyop.gear_mulmatrix_op( int_matrix.attr("output"), self.interpolate_lvl.attr("parentInverseMatrix[0]"), self.interpolate_lvl, ) # match roll ctl npo to ctrn_loc current transform (so correct orient) transform.matchWorldTransform(self.ctrn_loc, self.roll_ctl_npo) # match roll ctl npo to interpolate transform current position pos = self.interpolate_lvl.getTranslation(space="world") self.roll_ctl_npo.setTranslation(pos, space="world") # parent constraint roll control npo to interpolate trans pm.parentConstraint(self.interpolate_lvl, self.roll_ctl_npo, mo=True) if self.settings["ikTR"]: # connect the control inputs outEff_dm = o_node.listConnections(c=True)[-1][1] inAttr = self.ikRot_npo.attr("translate") outEff_dm.attr("outputTranslate") >> inAttr outEff_dm.attr("outputScale") >> self.ikRot_npo.attr("scale") dm_node = node.createDecomposeMatrixNode(o_node.attr("outB")) dm_node.attr("outputRotate") >> self.ikRot_npo.attr("rotate") # rotation mulM_node = applyop.gear_mulmatrix_op( self.ikRot_ctl.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix"), ) intM_node = applyop.gear_intmatrix_op( o_node.attr("outEff"), mulM_node.attr("output"), o_node.attr("blend"), ) dm_node = node.createDecomposeMatrixNode(intM_node.attr("output")) dm_node.attr("outputRotate") >> self.eff_loc.attr("rotate") transform.matchWorldTransform(self.fk2_ctl, self.ikRot_cns) # scale: this fix the scalin popping issue intM_node = applyop.gear_intmatrix_op( self.fk2_ctl.attr("worldMatrix"), self.ik_ctl_ref.attr("worldMatrix"), o_node.attr("blend"), ) mulM_node = applyop.gear_mulmatrix_op( intM_node.attr("output"), self.eff_loc.attr("parentInverseMatrix")) dm_node = node.createDecomposeMatrixNode(mulM_node.attr("output")) dm_node.attr("outputScale") >> self.eff_loc.attr("scale") pm.connectAttr(self.blend_att, o_node + ".blend") if self.negate: mulVal = -1 rollMulVal = 1 else: mulVal = 1 rollMulVal = -1 roll_m_node = node.createMulNode(self.roll_att, mulVal) roll_m_node2 = node.createMulNode(self.roll_ctl.attr("rx"), rollMulVal) node.createPlusMinusAverage1D( [roll_m_node.outputX, roll_m_node2.outputX], operation=1, output=o_node + ".roll", ) pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # Twist references --------------------------------- pm.pointConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) pm.connectAttr(self.mid_ctl.scaleX, self.tws1_loc.scaleX) pm.orientConstraint(self.mid_ctl_twst_ref, self.tws1_npo, maintainOffset=False) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.root.attr("worldInverseMatrix"), ) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws2_npo.attr("translate")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws2_npo.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws2_rot.attr("parentInverseMatrix"), ) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") attribute.setRotOrder(self.tws2_rot, "XYZ") pm.connectAttr(dm_node + ".outputRotate", self.tws2_rot + ".rotate") if self.settings["div0"]: ori_ref = self.rollRef[0] else: ori_ref = self.bone0 applyop.oriCns(ori_ref, self.tws0_loc, maintainOffset=True) self.tws0_rot.setAttr("sx", 0.001) self.tws2_rot.setAttr("sx", 0.001) add_node = node.createAddNode(self.roundness_att, 0.0) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) pm.connectAttr(self.armpit_roll_att, self.tws0_rot + ".rotateX") # Roll Shoulder applyop.splineIK( self.getName("rollRef"), self.rollRef, parent=self.root, cParent=self.bone0, ) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_loc) distB_node = node.createDistNode(self.tws1_loc, self.tws2_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" if self.settings["extraTweak"]: for tweak_ctl in self.tweak_ctl: for shp in tweak_ctl.getShapes(): pm.connectAttr(self.tweakVis_att, shp.attr("visibility")) # Divisions ---------------------------------------- # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll for i, div_cns in enumerate(self.div_cns): if i < (self.settings["div0"] + 1): perc = i * 0.5 / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = 0.501 else: perc = 0.5 + (i - self.settings["div0"] - 1.0) * 0.5 / (self.settings["div1"] + 1.0) perc = max(0.001, min(0.999, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws2_rot, self.tws1_rot, self.tws0_rot], 1.0 - perc, 40, ) else: o_node = applyop.gear_rollsplinekine_op( div_cns, [self.tws0_rot, self.tws1_rot, self.tws2_rot], perc, 40, ) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") # Squash n Stretch o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # match IK/FK ref pm.parentConstraint(self.bone0, self.match_fk0_off, mo=True) pm.parentConstraint(self.bone1, self.match_fk1_off, mo=True) if self.settings["ikTR"]: transform.matchWorldTransform(self.ikRot_ctl, self.match_ikRot) transform.matchWorldTransform(self.fk_ctl[2], self.match_fk2) # recover hand offset transform if self.settings["use_blade"]: self.eff_jnt_off.setMatrix(self.off_t, worldSpace=True)
def _create_curveInfo(self): #create a new CurveInfo Node self._curveInfo = pm.createNode("curveInfo", n=self._curveNode + "_curveInfo") pm.connectAttr(self._curveNode.worldSpace, self._curveInfo.inputCurve) return self._curveInfo
def __init__(self, objName, jointsNumber, groupJnts, curve, startJoint): self.objName = objName self.jointsNumber = jointsNumber self.groupJnts = groupJnts self.curve = curve self.startJoint = startJoint motionPathList = [] #curveSpans = pm.getAttr(self.curve + 'Shape.spans') if (self.curve == '') or (pm.objExists(self.curve) == False): childStartJoint = pm.listRelatives(self.startJoint) posStart = pm.xform(self.startJoint, q=True, t=True, ws=True) posEnd = pm.xform(childStartJoint, q=True, t=True, ws=True) autoGenCv = pm.curve(n=self.startJoint + '_twistJointsChain_CRV', d=1, p=[posStart, posEnd]) self.curve = autoGenCv pm.rebuildCurve(self.curve, ch=True, rt=0, rpo=True, end=1, kr=0, kep=True, kt=0, d=3, s=10) else: pm.rebuildCurve(self.curve, ch=True, rt=0, rpo=True, end=1, kr=0, kep=True, kt=0, d=3, s=10) pm.skinCluster(self.startJoint, childStartJoint, self.curve) pm.select(cl=True) groupTwistJoints = pm.group(n=self.groupJnts) nameTwistJoint = self.startJoint[0:len(self.startJoint) - 4] for i in range(0, self.jointsNumber): newJnt = pm.joint(n=nameTwistJoint + '_twist_' + str(i + 1) + '_JNT', radius=0.25) pm.setAttr(newJnt + '.overrideEnabled', 1) pm.setAttr(newJnt + '.overrideColor', 13) pm.parent(newJnt, groupTwistJoints) # motionPath = pm.pathAnimation(newJnt, c=self.curve, fractionMode = 0, eu = 1) motionPath = pm.createNode('motionPath') motionPathList.append(motionPath) pm.connectAttr(self.curve + 'Shape.worldSpace[0]', motionPath + '.geometryPath') pm.connectAttr(motionPath + '.xCoordinate', newJnt + '.tx', f=True) pm.connectAttr(motionPath + '.yCoordinate', newJnt + '.ty', f=True) pm.connectAttr(motionPath + '.zCoordinate', newJnt + '.tz', f=True) pm.connectAttr(motionPath + '.message', newJnt + '.specifiedManipLocation', f=True) maxValueCurve = pm.getAttr(self.curve + '.maxValue') print maxValueCurve # pm.cutKey(motionPath+'.u') pm.setAttr(motionPath + '.u', i * (maxValueCurve / (self.jointsNumber - 1))) pm.disconnectAttr(newJnt + '.tx') pm.disconnectAttr(newJnt + '.ty') pm.disconnectAttr(newJnt + '.tz') jointlist = pm.listRelatives(self.groupJnts, c=True) #print list for i in range(0, len(jointlist)): if i == 0: continue else: pm.parent(jointlist[i], jointlist[i - 1]) pm.joint(jointlist[0], e=True, oj='yxz', secondaryAxisOrient='zup', ch=True, zso=True) pm.joint(jointlist[len(jointlist) - 1], e=True, oj='none', ch=True, zso=True) for i in range(1, len(jointlist)): pm.parent(jointlist[i], groupTwistJoints) for i in range(0, len(motionPathList)): pm.connectAttr(motionPathList[i] + '.xCoordinate', jointlist[i] + '.tx', f=True) pm.connectAttr(motionPathList[i] + '.yCoordinate', jointlist[i] + '.ty', f=True) pm.connectAttr(motionPathList[i] + '.zCoordinate', jointlist[i] + '.tz', f=True)
def addOperators(self): # Tangent position --------------------------------- # common part d = vec.getDistance(self.guide.pos["root"], self.guide.pos["neck"]) dist_node = nod.createDistNode(self.root, self.ik_ctl) rootWorld_node = nod.createDecomposeMatrixNode(self.root.attr("worldMatrix")) div_node = nod.createDivNode(dist_node+".distance", rootWorld_node+".outputScaleX") div_node = nod.createDivNode(div_node+".outputX", d) # tan0 mul_node = nod.createMulNode(self.tan0_att, self.tan0_loc.getAttr("ty")) res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX") pm.connectAttr( res_node+".outputX", self.tan0_loc+".ty") # tan1 mul_node = nod.createMulNode(self.tan1_att, self.tan1_loc.getAttr("ty")) res_node = nod.createMulNode(mul_node+".outputX", div_node+".outputX") pm.connectAttr( res_node+".outputX", self.tan1_loc.attr("ty")) # Curves ------------------------------------------- op = aop.gear_curveslide2_op(self.slv_crv, self.mst_crv, 0, 1.5, .5, .5) pm.connectAttr(self.maxstretch_att, op+".maxstretch") pm.connectAttr(self.maxsquash_att, op+".maxsquash") pm.connectAttr(self.softness_att, op+".softness") # Volume driver ------------------------------------ crv_node = nod.createCurveInfoNode(self.slv_crv) # Division ----------------------------------------- for i in range(self.settings["division"]): # References u = i / (self.settings["division"] - 1.0) cns = aop.pathCns(self.div_cns[i], self.slv_crv, False, u, True) cns.setAttr("frontAxis", 1)# front axis is 'Y' cns.setAttr("upAxis", 2)# front axis is 'Z' # Roll intMatrix = aop.gear_intmatrix_op(self.intMRef+".worldMatrix", self.ik_ctl+".worldMatrix", u) dm_node = nod.createDecomposeMatrixNode(intMatrix+".output") pm.connectAttr(dm_node+".outputRotate", self.twister[i].attr("rotate")) pm.parentConstraint(self.twister[i], self.ref_twist[i], maintainOffset=True) pm.connectAttr(self.ref_twist[i]+".translate", cns+".worldUpVector") # Squash n Stretch op = aop.gear_squashstretch2_op(self.fk_npo[i], self.root, pm.arclen(self.slv_crv), "y") pm.connectAttr(self.volume_att, op+".blend") pm.connectAttr(crv_node+".arcLength", op+".driver") pm.connectAttr(self.st_att[i], op+".stretch") pm.connectAttr(self.sq_att[i], op+".squash") op.setAttr("driver_min", .1) # scl compas if i != 0: div_node = nod.createDivNode([1,1,1], [self.fk_npo[i-1]+".sx", self.fk_npo[i-1]+".sy", self.fk_npo[i-1]+".sz"]) pm.connectAttr(div_node+".output", self.scl_npo[i]+".scale") # Controlers if i == 0: mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"), self.root.attr("worldInverseMatrix")) else: mulmat_node = aop.gear_mulmatrix_op(self.div_cns[i].attr("worldMatrix"), self.div_cns[i - 1].attr("worldInverseMatrix")) dm_node = nod.createDecomposeMatrixNode(mulmat_node+".output") pm.connectAttr(dm_node+".outputTranslate", self.fk_npo[i].attr("t")) pm.connectAttr(dm_node+".outputRotate", self.fk_npo[i].attr("r")) # Orientation Lock if i == self.settings["division"] - 1 : dm_node = nod.createDecomposeMatrixNode(self.ik_ctl+".worldMatrix") blend_node = nod.createBlendNode([dm_node+".outputRotate%s"%s for s in "XYZ"], [cns+".rotate%s"%s for s in "XYZ"], self.lock_ori_att) self.div_cns[i].attr("rotate").disconnect() pm.connectAttr(blend_node+".output", self.div_cns[i]+".rotate") # Head --------------------------------------------- self.fk_ctl[-1].addChild(self.head_cns) #scale compensation dm_node = nod.createDecomposeMatrixNode(self.scl_npo[0]+".parentInverseMatrix") pm.connectAttr(dm_node+".outputScale", self.scl_npo[0]+".scale")
def paperbloc_gen(sel=None, w=21.0, d=29.7, h=2, num_sheets=10, max_xz=0.5, max_rot=10.0, name='paperbloc'): sel = paperbloc_base(w, d, h, name) if not sel: # Get Current selection sel = pmc.ls(sl=True) elif not isinstance(sel, list): sel = [sel] if len(sel) != 2: raise ValueError( 'Select Two Objects please, the fill paper and the paper bloc.') sSel = sel bloc_paper = sel[-1] sel = sel[0] print(bloc_paper) # check if the name already is in the scene i = 0 num = 1 while i < num: chk = pmc.ls(name + '_' + str(i)) if chk: num += 1 i += 1 if i == num: num -= 1 name_grp = name + '_grp_' + str(num) name_fill = name + '_fill_' + str(num) name = name + '_' + str(num) bloc_paper = pmc.duplicate(bloc_paper, n=name) fill_sheets = [bloc_paper[0]] #raise ValueError('STOP DOGGIE') for i in range(num_sheets): r_seed_x = random() * max_xz r_seed_y = random() * h r_seed_z = random() * max_xz r_seed_rot = random() * max_rot coin = coin_toss() if coin == 1: r_seed_rot = -r_seed_rot coin = coin_toss() if coin_toss == 1: r_seed_z = -r_seed_z coin = coin_toss() if coin_toss == 1: r_seed_x = -r_seed_x base_y = pmc.getAttr(sel.translateY) y_val = r_seed_y + base_y n_paper = pmc.duplicate(sel, n=name_fill) n_paper = n_paper[0] coin = coin_toss() if coin == 1: r_pivotx = random() * 10.0 r_pivotz = random() * 10.0 coin = coin_toss() if coin == 1: r_pivotx = -r_pivotx coin = coin_toss() if coin == 1: r_pivotz = -r_pivotz pmc.move(n_paper.rotatePivot, r_pivotx, 0, r_pivotz) pmc.setAttr(n_paper.ty, y_val) pmc.setAttr(n_paper.tx, r_seed_x) pmc.setAttr(n_paper.tz, r_seed_z) pmc.setAttr(n_paper.ry, r_seed_rot) fill_sheets.append(n_paper) print('---------feuilles placees -----------') print(fill_sheets) bender = pmc.nonLinear(fill_sheets, type='bend') print('bend creation') pmc.rename(bender[0], name + '__bend') pmc.rename(bender[-1], name + '__bendHandle') print('---------bend done -----------') pmc.setAttr(bender[-1].rotateZ, 90) fill_sheets.append(bender[0]) fill_sheets.append(bender[-1]) grp = pmc.group(em=True, n=name_grp) pmc.setAttr(grp.ty, base_y) pmc.parent(fill_sheets, grp) ar.zero_out(mc.ls(str(bender[-1]))) pmc.addAttr(grp, ln='bend_me', at='float', k=True) pmc.addAttr(grp, ln='bend_shift', at='float', k=True) pmc.addAttr(grp, ln='bend_min', at='float', min=-10, dv=-1, max=0, k=True) pmc.addAttr(grp, ln='bend_max', at='float', min=0, dv=1, max=10, k=True) pmc.addAttr(grp, ln='pos_bendx', at='float', k=True) pmc.addAttr(grp, ln='pos_bendz', at='float', k=True) pmc.connectAttr(grp.bend_me, bender[0].curvature) pmc.connectAttr(grp.bend_shift, bender[-1].rx) pmc.connectAttr(grp.bend_min, bender[0].lowBound) pmc.connectAttr(grp.bend_max, bender[0].highBound) pmc.connectAttr(grp.pos_bendx, bender[-1].ty) pmc.connectAttr(grp.pos_bendz, bender[-1].tz) pmc.delete(sSel) pmc.select(pmc.ls(grp)) return grp
def __init__( self, neckJoints, headJnt, #neckCurve, prefix='neck', rigScale=1.0, baseRig=None): """ :param neckJoints: list( str ), list of neck joints :param headJnt: str, head joint at the end of neck joint chain :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: instance of base.module.Base class :return: dictionary with rig module objects """ # :param neckCurve: str, name of neck cubic curve with 5 CVs matching neck joints # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # make IK handle neckIk, effector, neckCurve = pm.ikHandle(n=prefix + '_IKH', sol='ikSplineSolver', sj=neckJoints[0], ee=neckJoints[-1], createCurve=True, numSpans=2) # rename curve pm.rename(neckCurve, prefix + '_CRV') # make neck curve clusters neckCurveCVs = pm.ls(neckCurve + '.cv[*]', fl=1) numNeckCVs = len(neckCurveCVs) neckCurveClusters = [] for i in range(numNeckCVs): cls = pm.cluster(neckCurveCVs[i], n=prefix + 'Cluster%d' % (i + 1))[1] neckCurveClusters.append(cls) pm.hide(neckCurveClusters) # parent neck curve pm.parent(neckCurve, self.rigmodule.partsNoTransGrp) # make attach groups self.bodyAttachGrp = pm.group(n=prefix + 'BodyAttach_GRP', em=1, p=self.rigmodule.partsGrp) self.baseAttachGrp = pm.group(n=prefix + 'BaseAttach_GRP', em=1, p=self.rigmodule.partsGrp) pm.delete(pm.pointConstraint(neckJoints[0], self.baseAttachGrp)) # make controls headMainCtrl = control.Control(prefix=prefix + 'HeadMain', translateTo=neckJoints[-1], rotateTo=headJnt, scale=rigScale * 5, parent=self.rigmodule.controlsGrp, shape='head') headLocalCtrl = control.Control(prefix=prefix + 'HeadLocal', translateTo=headJnt, rotateTo=headJnt, scale=rigScale * 4, parent=headMainCtrl.C, shape='circleX', lockChannels=['t']) middleCtrl = control.Control(prefix=prefix + 'Middle', translateTo=neckCurveClusters[2], rotateTo=neckJoints[2], scale=rigScale * 4, parent=self.rigmodule.controlsGrp, shape='circleX', lockChannels=['r']) # attach controls pm.parentConstraint(headMainCtrl.C, self.baseAttachGrp, middleCtrl.Off, sr=['x', 'y', 'z'], mo=1) pm.orientConstraint(self.baseAttachGrp, middleCtrl.Off, mo=1) pm.parentConstraint(self.bodyAttachGrp, headMainCtrl.Off, mo=1) # attach clusters pm.parent(neckCurveClusters[3:], headMainCtrl.C) pm.parent(neckCurveClusters[2], middleCtrl.C) pm.parent(neckCurveClusters[:2], self.baseAttachGrp) # attach joints pm.orientConstraint(headLocalCtrl.C, headJnt, mo=1) pm.hide(neckIk) pm.parent(neckIk, self.rigmodule.partsNoTransGrp) # setup IK twist pm.setAttr(neckIk + '.dTwistControlEnable', 1) pm.setAttr(neckIk + '.dWorldUpType', 4) pm.connectAttr(headMainCtrl.C + '.worldMatrix[0]', neckIk + '.dWorldUpMatrixEnd') pm.connectAttr(self.baseAttachGrp + '.worldMatrix[0]', neckIk + '.dWorldUpMatrix')
import pymel.core as pm sel = pm.ls(sl=True) ctrl = sel[1].replace('Ctrl', 'Master_ctrl') closestPoint = pm.createNode('closestPointOnSurface', n='closestPointonSurface_node') arcLength = pm.createNode('arcLengthDimension', n='arcLengthDimension_node') pos = pm.xform(sel[1], q=True, t=True, ws=True) pm.connectAttr(sel[0] + '.local', closestPoint + '.inputSurface', f=1) pm.setAttr(closestPoint + '.inPosition', pos[0], pos[1], pos[2]) pm.connectAttr(sel[0] + '.worldSpace', arcLength + '.nurbsGeometry') pm.group(em=True, n='temp') pm.connectAttr(closestPoint + '.parameterU', 'temp.tx') pm.connectAttr(closestPoint + '.parameterV', 'temp.ty') paraU = pm.getAttr('temp.tx') paraV = pm.getAttr('temp.ty') pm.setAttr(arcLength + '.uParamValue', paraU) pm.setAttr(arcLength + '.vParamValue', paraV) pm.connectAttr(arcLength + '.arcLength', 'temp.sx') pm.connectAttr(arcLength + '.arcLengthInV', 'temp.sy') arclenU = pm.getAttr('temp.sx') arclenV = pm.getAttr('temp.sy') pm.delete('temp', pm.listRelatives(arcLength, p=True), arcLength, closestPoint) flc = pm.createNode('follicle', n=ctrl + '_follicleShape') pm.connectAttr(sel[0] + '.local', flc + '.inputSurface') pm.connectAttr(sel[0] + '.worldMatrix', flc + '.inputWorldMatrix')
def addOperators(self): """Create operators and set the relations for the component rig Apply operators, constraints, expressions to the hierarchy. In order to keep the code clean and easier to debug, we shouldn't create any new object in this method. """ # Visibilities ------------------------------------- # fk fkvis_node = node.createReverseNode(self.blend_att) for shp in self.fk0_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk0_roll_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) for shp in self.fk1_roll_ctl.getShapes(): pm.connectAttr(fkvis_node + ".outputX", shp.attr("visibility")) fkvis2_node = node.createReverseNode(self.blend2_att) for shp in self.fk2_ctl.getShapes(): pm.connectAttr(fkvis2_node + ".outputX", shp.attr("visibility")) # ik for shp in self.upv_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ikcns_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.ik_ctl.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) for shp in self.line_ref.getShapes(): pm.connectAttr(self.blend_att, shp.attr("visibility")) # jnt ctl for ctl in (self.div_ctls): for shp in ctl.getShapes(): pm.connectAttr(self.jntctl_vis_att, shp.attr("visibility")) # Controls ROT order ----------------------------------- attribute.setRotOrder(self.ik_ctl, "XZY") # IK Solver ----------------------------------------- out = [self.bone0, self.bone1, self.ctrn_loc, self.eff_npo] o_node = applyop.gear_ikfk2bone_op(out, self.root, self.ik_ref, self.upv_ctl, self.fk0_mtx, self.fk1_mtx, self.fk2_mtx, self.length0, self.length1, self.negate) pm.connectAttr(self.blend_att, o_node + ".blend") if self.negate: mulVal = -1 else: mulVal = 1 node.createMulNode(self.roll_att, mulVal, o_node + ".roll") pm.connectAttr(self.scale_att, o_node + ".scaleA") pm.connectAttr(self.scale_att, o_node + ".scaleB") pm.connectAttr(self.maxstretch_att, o_node + ".maxstretch") pm.connectAttr(self.slide_att, o_node + ".slide") pm.connectAttr(self.softness_att, o_node + ".softness") pm.connectAttr(self.reverse_att, o_node + ".reverse") # update issue on effector scale interpolation, disconnect # for stability pm.disconnectAttr(self.eff_npo.scale) # auto upvector ------------------------------------- # leg aim o_node = applyop.aimCns(self.upv_auv, self.ik_ctl, axis="-yz", wupType=1, wupVector=[0, 1, 0], wupObject=self.upv2_auv, maintainOffset=False) # foot aim o_node = applyop.aimCns(self.upv1_auv, self.root, axis="yz", wupType=4, wupVector=[0, 1, 0], wupObject=self.root, maintainOffset=False) # auto upvector connection o_node = applyop.gear_mulmatrix_op( self.upv_auv.attr("worldMatrix"), self.upv_mtx.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pb_node = pm.createNode("pairBlend") pb_node.attr("rotInterpolation").set(1) pm.connectAttr(dm_node + ".outputTranslate", pb_node + ".inTranslate2") pm.connectAttr(dm_node + ".outputRotate", pb_node + ".inRotate2") pm.connectAttr(pb_node + ".outRotate", self.upv_mtx.attr("rotate")) pm.connectAttr(pb_node + ".outTranslate", self.upv_mtx.attr("translate")) pm.connectAttr(self.auv_att, pb_node + ".weight") # fk0 mtx parent constraint o_node = applyop.gear_mulmatrix_op( self.fk0_roll_ctl.attr("worldMatrix"), self.fk0_mtx.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk0_mtx.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.fk0_mtx.attr("rotate")) # fk1 loc to fk1 ref parent constraint o_node = applyop.gear_mulmatrix_op( self.fk1_ref.attr("worldMatrix"), self.fk1_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk1_loc.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.fk1_loc.attr("rotate")) # fk1 mtx orient cns to fk1 roll pm.connectAttr(self.fk1_roll_ctl.attr("rotate"), self.fk1_mtx.attr("rotate")) # fk2_loc position constraint to effector------------------------ o_node = applyop.gear_mulmatrix_op( self.eff_npo.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.fk2_loc.attr("translate")) # fk2_loc rotation constraint to bone1 ------------------------ o_node = applyop.gear_mulmatrix_op( self.bone1.attr("worldMatrix"), self.fk2_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.fk2_loc.attr("rotate")) # foot ikfk blending from fk ref to ik ref (serious bugfix)---- o_node = applyop.gear_mulmatrix_op( self.fk_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pb_node = pm.createNode("pairBlend") pb_node.attr("rotInterpolation").set(1) pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", pb_node + ".inRotate1") pm.connectAttr(self.blend2_att, pb_node + ".weight") pm.connectAttr(pb_node + ".outRotate", self.eff_loc.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.ik_ref.attr("worldMatrix"), self.eff_loc.attr("parentInverseMatrix")) dm_node1 = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node1 + ".inputMatrix") pm.connectAttr(dm_node1 + ".outputRotate", pb_node + ".inRotate2") # use blendcolors to blend scale bc_node = pm.createNode("blendColors") pm.connectAttr(self.blend_att, bc_node + ".blender") pm.connectAttr(dm_node + ".outputScale", bc_node + ".color2") pm.connectAttr(dm_node1 + ".outputScale", bc_node + ".color1") pm.connectAttr(bc_node + ".output", self.eff_loc.attr("scale")) # Twist references --------------------------------- pm.connectAttr(self.mid_ctl.attr("translate"), self.tws1_npo.attr("translate")) pm.connectAttr(self.mid_ctl.attr("rotate"), self.tws1_npo.attr("rotate")) pm.connectAttr(self.mid_ctl.attr("scale"), self.tws1_npo.attr("scale")) o_node = applyop.gear_mulmatrix_op( self.eff_loc.attr("worldMatrix"), self.tws3_npo.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.tws3_npo.attr("translate")) o_node = applyop.gear_mulmatrix_op( self.bone1.attr("worldMatrix"), self.tws3_npo.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws3_npo.attr("rotate")) o_node = applyop.gear_mulmatrix_op( self.tws_ref.attr("worldMatrix"), self.tws3_rot.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputRotate", self.tws3_rot.attr("rotate")) # knee thickness connection if self.negate: o_node = node.createMulNode( [self.knee_thickness_att, self.knee_thickness_att], [0.5, -0.5, 0], [self.tws1_loc + ".translateX", self.tws2_loc + ".translateX"]) else: o_node = node.createMulNode( [self.knee_thickness_att, self.knee_thickness_att], [-0.5, 0.5, 0], [self.tws1_loc + ".translateX", self.tws2_loc + ".translateX"]) # connect both tws1 and tws2 (mid tws) self.tws0_rot.setAttr("sx", .001) self.tws3_rot.setAttr("sx", .001) add_node = node.createAddNode(self.roundness0_att, .001) pm.connectAttr(add_node + ".output", self.tws1_rot.attr("sx")) add_node = node.createAddNode(self.roundness1_att, .001) pm.connectAttr(add_node + ".output", self.tws2_rot.attr("sx")) # Roll Shoulder--use aimconstraint withour uovwctor to solve the # stable twist if self.negate: o_node = applyop.aimCns(self.tws0_loc, self.mid_ctl, axis="-xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.tws0_npo, maintainOffset=False) else: o_node = applyop.aimCns(self.tws0_loc, self.mid_ctl, axis="xy", wupType=4, wupVector=[0, 1, 0], wupObject=self.tws0_npo, maintainOffset=False) # Volume ------------------------------------------- distA_node = node.createDistNode(self.tws0_loc, self.tws1_npo) distB_node = node.createDistNode(self.tws1_npo, self.tws3_loc) add_node = node.createAddNode(distA_node + ".distance", distB_node + ".distance") div_node = node.createDivNode(add_node + ".output", self.root.attr("sx")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(self.root.attr("worldMatrix"), dm_node + ".inputMatrix") div_node2 = node.createDivNode(div_node + ".outputX", dm_node + ".outputScaleX") self.volDriver_att = div_node2 + ".outputX" # Divisions ---------------------------------------- # div mid constraint to mid ctl o_node = applyop.gear_mulmatrix_op( self.mid_ctl.attr("worldMatrix"), self.div_mid.attr("parentInverseMatrix")) dm_node = pm.createNode("decomposeMatrix") pm.connectAttr(o_node + ".output", dm_node + ".inputMatrix") pm.connectAttr(dm_node + ".outputTranslate", self.div_mid.attr("translate")) pm.connectAttr(dm_node + ".outputRotate", self.div_mid.attr("rotate")) # at 0 or 1 the division will follow exactly the rotation of the # controler.. and we wont have this nice tangent + roll scl_1_perc = [] scl_2_perc = [] for i, div_cnsUp in enumerate(self.div_cnsUp): if i < (self.settings["div0"] + 1): perc = i / (self.settings["div0"] + 1.0) elif i < (self.settings["div0"] + 2): perc = .95 perc = max(.001, min(.99, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cnsUp, [self.tws1_rot, self.tws0_rot], 1 - perc, 20) else: o_node = applyop.gear_rollsplinekine_op( div_cnsUp, [self.tws0_rot, self.tws1_rot], perc, 20) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") scl_1_perc.append(perc / 2) scl_2_perc.append(perc) scl_1_perc.append(0.5) scl_2_perc.append(1) for i, div_cnsDn in enumerate(self.div_cnsDn): if i == (0): perc = .05 elif i < (self.settings["div1"] + 1): perc = i / (self.settings["div1"] + 1.0) elif i < (self.settings["div1"] + 2): perc = .95 perc = max(.001, min(.990, perc)) # Roll if self.negate: o_node = applyop.gear_rollsplinekine_op( div_cnsDn, [self.tws3_rot, self.tws2_rot], 1 - perc, 20) else: o_node = applyop.gear_rollsplinekine_op( div_cnsDn, [self.tws2_rot, self.tws3_rot], perc, 20) pm.connectAttr(self.resample_att, o_node + ".resample") pm.connectAttr(self.absolute_att, o_node + ".absolute") scl_1_perc.append(perc / 2 + 0.5) scl_2_perc.append(1 - perc) # Squash n Stretch for i, div_cns in enumerate(self.div_cns): o_node = applyop.gear_squashstretch2_op( div_cns, None, pm.getAttr(self.volDriver_att), "x") pm.connectAttr(self.volume_att, o_node + ".blend") pm.connectAttr(self.volDriver_att, o_node + ".driver") pm.connectAttr(self.st_att[i], o_node + ".stretch") pm.connectAttr(self.sq_att[i], o_node + ".squash") # get the first mult_node after sq op mult_node = pm.listHistory(o_node, future=True)[1] # linear blend effector scale bc_node = pm.createNode("blendColors") bc_node.setAttr("color2R", 1) bc_node.setAttr("color2G", 1) bc_node.setAttr("blender", scl_1_perc[i]) pm.connectAttr(self.eff_loc.attr("scale"), bc_node + ".color1") # linear blend mid scale bc_node2 = pm.createNode("blendColors") bc_node2.setAttr("color2R", 1) bc_node2.setAttr("color2G", 1) bc_node2.setAttr("blender", scl_2_perc[i]) pm.connectAttr(self.mid_ctl.attr("scale"), bc_node2 + ".color1") # mid_ctl scale * effector scale mult_node2 = pm.createNode("multiplyDivide") pm.connectAttr(bc_node2 + ".output", mult_node2 + ".input1") pm.connectAttr(bc_node + ".output", mult_node2 + ".input2") # plug to sq scale pm.connectAttr(mult_node2 + ".output", mult_node + ".input2") # match IK/FK ref pm.connectAttr(self.bone0.attr("rotate"), self.match_fk0.attr("rotate")) pm.connectAttr(self.bone0.attr("translate"), self.match_fk0.attr("translate")) pm.connectAttr(self.bone1.attr("rotate"), self.match_fk1.attr("rotate")) pm.connectAttr(self.bone1.attr("translate"), self.match_fk1.attr("translate")) return