def deleteShotSculptFrame(): if editState == True: editSculptFrame() ssn = pm.optionMenu("selectedSSNode_menu", q=True, v=True) bshps = pm.getAttr(ssn + '.bshps') frame = pm.textScrollList("SculptLayers_tsl", q=True, si=True) result = pm.confirmDialog(title='Delete Sculpt-Frame', message='Are you sure you want to delete ' + frame[0] + "?", button=['Yes', 'No'], defaultButton='Yes', cancelButton='No', dismissString='No') if result == 'Yes': pm.deleteAttr(ssn + '.' + frame[0]) pm.textScrollList("SculptLayers_tsl", e=True, ri=str(frame[0])) for bshp in bshps: ##mel command: blendShapeDeleteTargetGroup + bshp + index index = getIndexByName(bshp, frame[0]) #remove the alias pm.aliasAttr(bshp + '.' + frame[0], remove=True) ##delete the target pm.removeMultiInstance(bshp + '.weight[' + str(index) + ']', b=True)
def addTargets(sourceObj=None, splittedTargets=list()): firstIndex = 0 bsNode = getBlendShapeNode(sourceObj) if bsNode: appliedTargetNames = pm.listAttr(bsNode.w, m=True) firstIndex = nextFreeIndex(bsNode) for i, target in enumerate(splittedTargets): if target.name() in appliedTargetNames: delete_blendshape_target(bsNode.name(), getIndexByName(bsNode, target.name())) pm.aliasAttr(bsNode.name() + '.' + target.name(), rm=True) pm.blendShape(bsNode, edit=True, t=(sourceObj.name(), i + firstIndex, target.name(), 1.0)) print('reapplying target{1} index {0}'.format( i + firstIndex, target.name())) pm.delete(splittedTargets) else: firstIndex = 0 pm.blendShape(splittedTargets, sourceObj) pm.delete(splittedTargets) return firstIndex
def completeStretchySetup( expr, expressionNode, characterNode, curveInfoNodeBack ): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit = True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleX') pm.connectAttr(characterNode+'.scaleY', characterNode+'.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def completeStretchySetup(expr, expressionNode, characterNode, curveInfoNodeBack): pymelLogger.debug('Starting: completeStretchySetup()...') # if stretchy back is selected # When scaling characterNode character breaks # because the backcurve is also scaling # applying two time scale # we need to edit ikcurve expression and change the scale to # $scale = (curveinfoName).normalizedScale/(characterNode).scaleY; endFirstLineExpr = expr.find('\n') slicedExpr = expr[endFirstLineExpr:] # Edit first line and add the old expression sliced newExpr = '$scale = ' + curveInfoNodeBack + '.normalizedScale/' + characterNode + '.scaleY;\n' newExpr += slicedExpr pm.expression(expressionNode, edit=True, string=newExpr) # To avoid scaling uniformally in x and z # the scale Y attr will drive X and Z pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleX') pm.connectAttr(characterNode + '.scaleY', characterNode + '.scaleZ') # Now we can lock and hide scale X and Z hideLockAttr(characterNode, lockHideXZ) # Change attr name of Scale Y to name = globalScale # it allows us to still use the scale manipulator # instead of adding a new attr for that pm.aliasAttr('globalScale', characterNode + '.scaleY') pymelLogger.debug('End: completeStretchySetup()...')
def initPlugin(self, type): meshes = pm.selected(tr=1) if not meshes: return pm.select( meshes[-1]) deformer = pm.ls(cmds.deformer(type=type)[0])[0] for i in range(len(meshes)-1): deformer.bw[i].set(0.0) shape=meshes[i].getShapes()[0] cmds.connectAttr(shape+".outMesh", deformer+".blendMesh[%s]" %(i)) pm.aliasAttr(meshes[i].name(), deformer.bw[i].name()) self.updateUI()
def addProbe(self,node,deformerType,newProbes): indexes = cmds.getAttr(node+".pm", multiIndices=True) if not indexes: n=0 else: n=indexes[-1]+1 # connect pm first to avoid unnecessary arap computations for j in range(len(newProbes)): cmds.connectAttr(newProbes[j]+".worldMatrix", node+".pm[%s]" %(j+n)) if deformerType=="probeDeformerARAP" or deformerType=="probeDeformer": pm.aliasAttr(newProbes[j].name()+"_weight%s" %(j+n), node.prw[j+n].name()) if deformerType=="probeDeformerARAP": pm.aliasAttr(newProbes[j].name()+"_constraintRadius%s" %(j+n), node.prcr[j+n].name()) for j in range(len(newProbes)): node.ipm[j+n].set(newProbes[j].worldMatrix.get())
def init_targets(self): if pm.objExists(self.bs_node): if pm.PyNode(self.bs_node).getTarget(): return {i: pm.aliasAttr('{}.w[{}]'.format(self.bs_node, i), q=1) for i in pm.getAttr('{}.w'.format(self.bs_node), multiIndices=1)} else: return None
def loadDriven(self, *args): """ Load object name for driven object in text field """ sel = pm.ls(sl=True, fl=True) pm.textFieldButtonGrp(self.drivenField, edit=True, text=sel[0]) # Clear the menu items so list doesn't grow items = pm.optionMenu(self.drivenAttField, q=True, ill=True) if(items): pm.setParent(self.drivenAttField, menu=True) for each in items: pm.deleteUI(each) # Check if blendshape if 'BlendShape' in str(type(sel[0])): bs = sel[0] temp = pm.aliasAttr(bs, q=1) temp.sort() targets = [] for each in temp: if each.startswith('weight'): continue targets.append(each) for tgt in targets: try: pm.menuItem(parent=self.drivenAttField, label=tgt) except Exception, e: print e pm.warning('%s failed to create / connect' % tgt)
def getIndexByName(blsNode, targetName): attr = blsNode + '.w[{}]' weightCount = pm.blendShape(blsNode, q=True, wc=True) for index in xrange(weightCount): if pm.aliasAttr(attr.format(index), q=True) == targetName: return index return -1
def refresh_src_blend_shape_list(self): pm.textScrollList('blendShapeTargetList', edit=True, removeAll=True) src_blend_shape = self.get_src_blend_shape_name() if src_blend_shape is None: return if src_blend_shape == 'No Blend Shape Selected': return # The blend shape array is sparse, so keep a mapping from list indices to blend # shape weight indices. Note that for some reason, these are 1-based. self.src_blend_shape_map = {} # Add the blend shape targets in the source blend shape to the list. src_blend_shape = pm.ls(src_blend_shape)[0] weight_idx_list = src_blend_shape.weightIndexList() src_weights = src_blend_shape.attr('weight') for weight_idx in weight_idx_list: weight = src_weights.elementByLogicalIndex(weight_idx) target_name = pm.aliasAttr(weight, q=True) pm.textScrollList('blendShapeTargetList', edit=True, append=target_name) idx = pm.textScrollList('blendShapeTargetList', q=True, numberOfItems=True) self.src_blend_shape_map[idx] = weight
def CreateTemporaryGroupRepresentation(self): #controlGrpFile = "%s/ControlObjects/Blueprint/controlGroup_control.ma" %self.directory controlGrpFile = "%s/ControlObjects/Blueprint/controlGroup_control.ma" %os.environ["RIGGING_TOOL_ROOT"] pm.importFile(controlGrpFile) self.tempGroupTransform = pm.rename("controlGroup_control", "Group__tempGroupTransform__") pm.connectAttr("%s.scaleY" %self.tempGroupTransform, "%s.scaleX" %self.tempGroupTransform) pm.connectAttr("%s.scaleY" %self.tempGroupTransform, "%s.scaleZ" %self.tempGroupTransform) for attr in ['scaleX', 'scaleZ', 'visibility']: pm.setAttr("%s.%s" %(self.tempGroupTransform, attr), lock = True, keyable = False) pm.aliasAttr('globalScale', "%s.scaleY" %self.tempGroupTransform)
def refresh(self, deformer): """ If a blendShape is selected, populate the list of targets. """ for item in pm.optionMenu(self.control_name + '|OptionMenu', q=True, itemListLong=True): pm.deleteUI(item) self.all_item = None # The blend shape array is sparse, so keep a mapping from list indices to blend # shape weight indices. Note that for some reason, these are 1-based. self.blend_shape_map.clear() if not isinstance(deformer, pm.nodetypes.BlendShape): return def add_target(name, shape_id): item = pm.menuItem(label=name, parent=self.control_name + '|OptionMenu') idx = pm.optionMenuGrp(self.control_name, q=True, numberOfItems=True) self.blend_shape_map[idx] = shape_id return item if self.all_text is not None: self.all_item = add_target(self.all_text, '(all)') add_target('Main deformer weights', '(main)') # Add the blend shape targets in the source blend shape to the list. for idx, weight in enumerate(deformer.attr('weight')): add_target('Target: ' + pm.aliasAttr(weight, q=True), weight)
def linkTheHooks(self): faceShapesGeo = "bsMan_fRig_PLY" faceGeo = "C_head_low_PLY" faceShapesGeoHis = pm.listHistory(faceShapesGeo) faceShapesBls = cmds.ls(faceShapesGeoHis, type="blendShape")[0] targetIndeces = pm.getAttr(faceShapesBls + ".weight", multiIndices=1) bsShapeNames = [ pm.aliasAttr("{0}.weight[{1}]".format(faceShapesBls, num), query=True) for num in targetIndeces ] faceBlendGRP = pm.group(empty=True, n="faceBlends_hooks") for x in bsShapeNames: pm.addAttr(faceBlendGRP, sn=x) hooks = pm.PyNode("faceBlends_hooks") # Check every blendshape for matching hook names. allBlends = pm.ls(type='blendShape') for newBlend in allBlends: for eachShape in newBlend.w: shapeName = eachShape.getAlias() if hooks.hasAttr(shapeName): hookAttr = hooks.attr(shapeName) try: hookAttr.connect(eachShape, force=True) except: continue pm.blendShape(faceShapesGeo, faceGeo, weight=[0, 1]) pm.setAttr(faceShapesGeo + ".visibility", 0)
def fill_blend_target(self, unused=True): # Clear the existing target list. for item in pm.optionMenu('sbsTargetList|OptionMenu', q=True, itemListLong=True): pm.deleteUI(item) # Prevent a warning from being printed if there aren't any blendShapes. if pm.optionMenuGrp('sbsList', q=True, ni=True) == 0: return # Get the names of the targets in the selected blend shape. value = pm.optionMenuGrp('sbsList', q=True, v=True) if not value: return nodes = pm.ls(value) if not nodes: return node = nodes[0] pm.menuItem(label='All', parent='sbsTargetList|OptionMenu') for item in node.attr('w'): target_name = pm.aliasAttr(item, q=True) pm.menuItem(label=target_name, parent='sbsTargetList|OptionMenu')
def get_blend_targets(mesh): """ :param mesh: pymel transform node. :return: blendShape node and a list of blendShape targets if found. """ attributes_dict = {} if type(mesh) is str: if len(pm.ls(mesh)) == 0: print 'could not find ', mesh return None mesh = pm.ls(mesh)[0] if type(mesh) is not pm.nodetypes.Transform: print 'MESH TYPE is not pymel transform', type(mesh) return if not mesh.listHistory(type='blendShape'): print 'Could not find Blendshape node for', mesh return None blend_shape_nodes = mesh.listHistory(type='blendShape') for node in blend_shape_nodes: blend_name = pm.aliasAttr(node, query=True) for key in blend_name: if key.find('weight[') == -1: print key, node attributes_dict[key] = node return attributes_dict
def create(cls, guideNode, name=None): """Create a new Handle object.""" handle = pm.createNode("guideHandle") transform = handle.getParent() if name: transform.rename(name) transform.worldMatrix[0].connect(handle.handleMatrix) transform.scaleY.connect(transform.scaleX) transform.scaleY.connect(transform.scaleZ) pm.aliasAttr("radius", transform.scaleY) lib.transform.lockHideTransforms(transform, translate="", rotate="", scale="xz") connectGuideToHandle(guideNode, handle) pm.select(transform) return cls(handle)
def nextFreeIndex(blsNode): allTargets = pm.aliasAttr(blsNode, q=True) weightList = allTargets[1::2] max_index = 0 for weight in weightList: split_w = re.split('\[(.*?)\]', str(weight)) index = int(split_w[1]) max_index = max(max_index, index) return max_index + 1
def createAliases(sg): # This will run on scene startup but the list of AOVs will be unknown if not sg: return if sg.name() == "swatchShadingGroup": return aovList = getAOVs() sgAttr = sg.aiCustomAOVs for aov in aovList: exists = False for at in sgAttr: if at.aovName.get() == aov.name: exists = True if not exists: i = nextAvailableIndex(sgAttr) at = sgAttr[i] at.aovName.set(aov.name) for at in sgAttr: name = at.aovName.get() try: pm.aliasAttr('ai_aov_' + name, at) except RuntimeError as err: pm.aliasAttr(sg + '.ai_aov_' + name, remove=True) pm.aliasAttr('ai_aov_' + name, at)
def rename(self, newName, oldName=None): ''' rename an AOV in the active list. provide oldName if the attribute has already been renamed and you just need to perform the proper bookkeeping ''' if oldName is None: oldName = self.name self.node.attr('name').set(newName) for sg in pm.ls(type='shadingEngine'): try: pm.aliasAttr(sg + '.ai_aov_' + oldName, remove=True) except RuntimeError, err: pass #print err sgAttr = sg.aiCustomAOVs try: pm.aliasAttr('ai_aov_' + newName, sgAttr[self.index]) except RuntimeError, err: pass #print err
def get_weight_from_alias(blend_shape, alias): """ Given a blend shape node and an aliased weight attribute, return the index in .weight to the alias. """ # aliasAttr lets us get the alias from an attribute, but it doesn't let us get the attribute # from the alias. existing_indexes = blend_shape.attr('weight').get(mi=True) or [] for idx in existing_indexes: aliasName = pm.aliasAttr(blend_shape.attr('weight').elementByLogicalIndex(idx), q=True) if aliasName == alias: return idx raise Exception('Couldn\'t find the weight index for blend shape target %s.%s' % (blend_shape, alias))
def linkTheHooks(self): conditionNode = [] multiplyNode = [] faceShapesGeoHis = pm.listHistory(FACE_SHAPES_GEO) faceShapesBls = pm.ls(faceShapesGeoHis, type="blendShape")[0] targetIndeces = pm.getAttr(faceShapesBls + ".weight", multiIndices=1) bsShapeNames = [pm.aliasAttr("{0}.weight[{1}]".format(faceShapesBls, num), query=True)for num in targetIndeces] faceBlendGRP = pm.group(empty=True, name="faceBlends_hooks") for x in bsShapeNames: pm.addAttr(faceBlendGRP, shortName=x) hooks = pm.PyNode("faceBlends_hooks") # Check every blendshape for matching hook names. allBlends = pm.ls(type='blendShape') for newBlend in allBlends: for eachShape in newBlend.w: shapeName = eachShape.getAlias() if hooks.hasAttr(shapeName): hookAttr = hooks.attr(shapeName) try: hookAttr.connect(eachShape, force=True) condition = pm.createNode("condition", name= "{0}".format(shapeName) + "_COND") pm.addAttr(condition, shortName=shapeName) pm.setAttr(condition + ".colorIfFalseR", 0) pm.setAttr(condition + ".operation", 2) multiply = pm.createNode("multiplyDivide", name= "{0}".format(shapeName) + "_MULT") pm.addAttr(multiply, shortName=shapeName) pm.setAttr(multiply + ".input2Y", -1) name = "l_pullDown", "r_pullDown", "l_frown", "r_frown", "l_lipsPullOut", "r_lipsPullsOut", "r_narrow" if multiply.startswith(name): pm.connectAttr(multiply + ".outputY", hookAttr) else: pm.connectAttr(multiply + ".outputX", hookAttr) conditionNode.append(condition) multiplyNode.append(multiply) except: pass for x, y in zip(conditionNode, multiplyNode): pm.connectAttr(x + ".outColorR", y + ".input1X", force=True) pm.connectAttr(x + ".outColorG", y + ".input1Y", force=True) pm.blendShape(FACE_SHAPES_GEO, FACE_GEO, weight=[0,1]) pm.setAttr(FACE_SHAPES_GEO + ".visibility", 0)
def loadModuleControl(root_joint, module_name, container, control_type = "module"): """ loads module control onto the root root_joint """ path = os.path.join(environ.ControlObjectsPath, "module_control-01.ma") pm.importFile(path, renameAll = True, loadReferenceDepth = "all", namespace =":") # renamePrefix == namespace # rename default module module_control = pm.rename("module_control", module_name + ":module_control", ignoreShape = False) # move control to root root_joint pm.delete(pm.pointConstraint(root_joint, module_control, maintainOffset=False)) # connect scaleX and scaleZ to scaleY pm.connectAttr(module_control + ".sy", module_control + ".sx") pm.connectAttr(module_control + ".sy", module_control + ".sz") # rename module control scale y to global scale pm.aliasAttr("GlobalScale", module_control + ".sy") # lock scale x and z module_control.setAttr("sx", lock=True, keyable=False, channelBox=False) module_control.setAttr("sz", lock=True, keyable=False, channelBox=False) pm.addAttr(module_control, longName="ControlType", dataType="string", keyable=False) module_control.ControlType.set(control_type, type = "string", lock = True) ''' utils.addNodeToContainer(container, module_control, ihb = True) pm.container(container, edit=True, publishAndBind=[module_control + ".translate", module_control.stripNamespace() + "_translate"]) pm.container(container, edit=True, publishAndBind=[module_control + ".rotate", module_control.stripNamespace() + "_rotate"]) pm.container(container, edit=True, publishAndBind=[module_control + ".scale", module_control.stripNamespace() + "_globalScale"]) ''' return module_control
def addAliases(aovs): for sg in pm.ls(type='shadingEngine'): sgAttr = sg.aiCustomAOVs nameMapping, nextIndex = getShadingGroupAOVMap(sgAttr) for aov in aovs: try: plug = nameMapping[aov.name] except KeyError: plug = sgAttr[nextIndex] plug.aovName.set(aov.name) try: pm.aliasAttr('ai_aov_' + aov.name, plug) except RuntimeError as err: pm.aliasAttr(sg + '.ai_aov_' + aov.name, remove=True) pm.aliasAttr('ai_aov_' + aov.name, plug)
import pymel.core as pm blendshape_ = pm.PyNode('tongue_target') geo_ = 'blend_tongue' # Origin geo new_target = 'blend_tongue' # Wrap target or same as geo_ geo_ = pm.PyNode(geo_) geo_shape = geo_.getShape() blendshape_list = pm.aliasAttr(blendshape_, q=1) blendshape_list = list(set(blendshape_list)) blendshape_list.sort() for i, target_ in enumerate(blendshape_list): blend_attr = pm.PyNode('%s.%s' % (blendshape_, target_)) value_list = [] name_list = [] ib_value_list = None # blendshape index value list try: ib_name_list = [] ib_value_list = blendshape_.targetItemIndexList( blend_attr.index(), geo_shape) if ib_value_list: for value_ in ib_value_list: eval_ = 'blendshape_' eval_ += '.inbetweenInfoGroup[%s]' % blend_attr.index() eval_ += '.inbetweenInfo[%s]' % value_ eval_ += '.inbetweenTargetName.get()' ib_name = eval(eval_) if ib_name != 'IB':
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 shapes = ['MouthAndSacShapes', 'NoseShapes'] controls = ['mouthShapes_ctrl', 'noseShapes_ctrl'] index = 0 for shape in shapes: pm.select(shape,r=1) bs = pm.ls(sl=1)[0] temp = pm.aliasAttr(bs,q=1) temp.sort() targets = [] for each in temp: if each.startswith('weight'): continue targets.append(each) for tgt in targets: try: pm.addAttr(controls[index],ln=tgt,k=1, min=0, max=1) pm.connectAttr('%s.%s'%(controls[index], tgt),'%s.%s'%(bs, tgt),f=1) except Exception,e: print e pm.warning('%s failed to create / connect'%tgt) index += 1
def Create(self, _name, _controlFile, _animationModuleInstance, _lod = 1, _translation = True, _rotation = True, _globalScale = True, _spaceSwitching = False): if _translation == True or _translation == False: translation = [_translation, _translation, _translation] if _rotation == True or _rotation == False: rotation = [_rotation, _rotation, _rotation] self.translation = translation self.rotation = rotation self.globalScale = _globalScale animationModuleName = _animationModuleInstance.moduleNamespace blueprintModuleNameSpace = _animationModuleInstance.blueprintNamespace blueprintModuleUserSpecifiedName = utils.StripAllNamespaces(blueprintModuleNameSpace)[1].partition("__")[2] animationModuleNamespace = "%s:%s" %(blueprintModuleNameSpace, animationModuleName) # import control object #controlObjectFile = "%s/ControlObjects/Animation/%s" %(self.directory, _controlFile) controlObjectFile = "%s/ControlObjects/Animation/%s" %(os.environ["RIGGING_TOOL_ROOT"], _controlFile) pm.importFile(controlObjectFile) self.controlObject = pm.rename("control", "%s:%s" %(animationModuleNamespace, _name)) self.rootParent = self.controlObject self.SetupIconScale(animationModuleNamespace) pm.setAttr("%s.overrideEnabled" %self.controlObject, 1) pm.setAttr("%s.overrideShading" %self.controlObject, 0) pm.connectAttr("%s:module_grp.overrideColor" %animationModuleNamespace, "%s.overrideColor" %self.controlObject) pm.container("%s:module_container" %animationModuleNamespace, edit = True, addNode = self.controlObject, includeHierarchyBelow = True, includeNetwork = True) if _globalScale: pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleX" %self.controlObject) pm.connectAttr("%s.scaleY" %self.controlObject, "%s.scaleZ" %self.controlObject) pm.aliasAttr("globalScale", "%s.scaleY" %self.controlObject) attributes = [] if self.translation == [True, True, True]: attributes.append([True, ".translate", "T"]) else: attributes.extend([[translation[0], ".translateX", "TX"], [translation[1], ".translateY", "TY"], [translation[2], ".translateZ", "TZ"]]) if self.rotation == [True, True, True]: attributes.append([True, ".rotate", "R"]) else: attributes.extend([[rotation[0], ".rotateX", "RX"], [rotation[1], ".rotateY", "RY"], [rotation[2], ".rotateZ", "RZ"]]) attributes.append([_globalScale, ".globalScale", "scale"]) for attrInfo in attributes: if attrInfo[0]: attributeNiceName = "%s_%s" %(_name, attrInfo[2]) _animationModuleInstance.PublishNameToModuleContainer("%s%s" %(self.controlObject, attrInfo[1]), attributeNiceName, True) pm.select(self.controlObject, replace = True) pm.addAttr(attributeType = "bool", defaultValue = 1, keyable = True, longName = "display") _animationModuleInstance.PublishNameToModuleContainer("%s.display" %self.controlObject, "display", False) moduleGrp = "%s:module_grp" %animationModuleNamespace visibilityExpression = '%s.visibility = %s.display * (%s.levelOfDetail >= %d);' %(self.controlObject, self.controlObject, moduleGrp, _lod) expression = pm.expression(name = "%s_visibility_expression" %self.controlObject, string = visibilityExpression) utils.AddNodeToContainer("%s:module_container" %animationModuleNamespace, expression) return (self.controlObject, self.rootParent)
def execute(self): self.prebuild() check_list = [ "{0}_RIG".format(self.model.character_name), "GEO_GRP", "CTRL_GRP", "JNT_GRP", "MESH_GRP", "PARTS_GRP", "global_CTRL", "{0}_global_OUTPUT".format(self.model.module_name), "{0}_local_INPUT".format(self.model.module_name), "{0}_local_ctrl_OFS".format(self.model.module_name), "{0}_local_CTRL".format(self.model.module_name), "{0}_local_ctrl_OUTPUT".format(self.model.module_name), "{0}_global_scale_MDL".format(self.model.module_name) ] if rig_lib.exists_check(check_list): pmc.select(cl=1) return if rig_lib.exists_check("{0}_RIG".format(self.model.character_name)): pmc.delete("{0}_RIG".format(self.model.character_name)) main_grp = pmc.group(em=1, n="{0}_RIG".format(self.model.character_name)) geo_grp = pmc.group(em=1, n="GEO_GRP") ctrl_grp = pmc.group(em=1, n="CTRL_GRP") jnt_grp = pmc.group(em=1, n="JNT_GRP") mesh_grp = pmc.group(em=1, n="MESH_GRP") parts_grp = pmc.group(em=1, n="PARTS_GRP") global_shape = rig_lib.square_arrow_curve( "{0}_global_CTRL_shape".format(self.model.module_name)) global_ctrl = rig_lib.create_jnttype_ctrl(name="global_CTRL", shape=global_shape, drawstyle=2) global_output = pmc.spaceLocator(p=(0, 0, 0), n="{0}_global_OUTPUT".format( self.model.module_name)) global_output.visibility.set(0) pmc.parent(geo_grp, ctrl_grp, jnt_grp, mesh_grp, parts_grp, global_ctrl, main_grp) pmc.parent(global_output, global_ctrl, r=1) local_input = pmc.group(em=1, n="{0}_local_ctrl_INPUT".format( self.model.module_name)) pmc.parent(local_input, ctrl_grp, r=1) rig_lib.matrix_constraint(global_output, local_input, srt="trs") local_shape = pmc.circle(c=(0, 0, 0), nr=(0, 1, 0), sw=360, r=5, d=3, s=8, n="{0}_local_CTRL_shape".format( self.model.module_name), ch=0)[0] local_ctrl = rig_lib.create_jnttype_ctrl(name="{0}_local_CTRL".format( self.model.module_name), shape=local_shape, drawstyle=2) pmc.parent(local_ctrl, local_input, r=1) rig_lib.create_output(name="{0}_local_ctrl_OUTPUT".format( self.model.module_name), parent=local_ctrl) global_scale_mult_node = pmc.createNode( "multDoubleLinear", n="{0}_global_mult_local_scale_MDL".format(self.model.module_name)) global_ctrl.scaleY >> global_ctrl.scaleX global_ctrl.scaleY >> global_ctrl.scaleZ local_ctrl.scaleY >> local_ctrl.scaleX local_ctrl.scaleY >> local_ctrl.scaleZ global_ctrl.scaleY >> global_scale_mult_node.input1 local_ctrl.scaleY >> global_scale_mult_node.input2 pmc.aliasAttr("global_scale", global_ctrl.scaleY) pmc.aliasAttr("local_scale", local_ctrl.scaleY) global_ctrl.setAttr("scaleX", lock=True, keyable=False, channelBox=False) global_ctrl.setAttr("scaleY", keyable=False, channelBox=True) global_ctrl.setAttr("scaleZ", lock=True, keyable=False, channelBox=False) local_ctrl.setAttr("scaleX", lock=True, keyable=False, channelBox=False) local_ctrl.setAttr("scaleY", keyable=False, channelBox=True) local_ctrl.setAttr("scaleZ", lock=True, keyable=False, channelBox=False) rig_lib.clean_ctrl(global_ctrl, 3, trs="") rig_lib.clean_ctrl(local_ctrl, 17, trs="") info_crv = rig_lib.signature_shape_curve("{0}_INFO".format( self.model.module_name)) info_crv.getShape().setAttr("visibility", 0) info_crv.setAttr("hiddenInOutliner", 1) info_crv.setAttr("translateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("translateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("rotateZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleX", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleY", lock=True, keyable=False, channelBox=False) info_crv.setAttr("scaleZ", lock=True, keyable=False, channelBox=False) info_crv.setAttr("visibility", lock=True, keyable=False, channelBox=False) info_crv.setAttr("overrideEnabled", 1) info_crv.setAttr("overrideDisplayType", 2) pmc.parent(info_crv, parts_grp) rig_lib.add_parameter_as_extra_attr(info_crv, "Module", "mandatory_base") rig_lib.add_parameter_as_extra_attr(info_crv, "character_name", self.model.character_name) pmc.select(cl=1)
def build_rbf(self): try: pm.loadPlugin('jsRadial.mll') except: pm.error('ERROR: jsRadial.mll not loaded.') pm.undoInfo(openChunk=True) rbf = pm.createNode('jsRadPose') # Notify if RBF is made with no connections if len(self.pose) == 0 and len(self.targets) == 0: print "RBF node made with no connections" # Only create one sigma blinn material if self.sigma_chk.isChecked(): self.sigma_shader = pm.shadingNode("lambert", asShader=True, name="sigmaLmbt") pm.setAttr(self.sigma_shader.color.colorR, 0.0) pm.setAttr(self.sigma_shader.color.colorG, 0.5) pm.setAttr(self.sigma_shader.color.colorB, 1.0) pm.setAttr(self.sigma_shader.transparency, (0.95, 0.95, 0.95)) self.sigma_sg = pm.sets(renderable=1, noSurfaceShader=1, empty=1, n="sigmaLmbt_SG") pm.connectAttr(self.sigma_shader.outColor, self.sigma_sg.surfaceShader) self.falloff_group = pm.group(empty=1, n="GRP_rbf_falloff") # Connect pose attrs if len(self.pose) == 1: # Connect pose matrix if self.matrix_chk.isChecked() == True: if self.world_rad.isChecked() == True: pm.connectAttr(self.pose[0][0].worldMatrix[0], rbf.poseMatrix) else: pm.connectAttr(self.pose[0][0].parentMatrix[0], rbf.poseMatrix) # Connect pose color if self.rgb_chk.isChecked() == True or self.alpha_chk.isChecked( ) == True: shape = pm.listRelatives(self.pose[0], shapes=1)[0] shader_grp = pm.listConnections(shape, type='shadingEngine') shader = pm.listConnections(shader_grp[0], d=0, s=1)[0] if self.rgb_chk.isChecked(): try: pm.connectAttr(shader.color, rbf.poseColor) except: try: pm.connectAttr(shader.outColor, rbf.poseColor) except: pass if self.alpha_chk.isChecked(): try: pm.connectAttr(shader.transparency, rbf.poseTransparency) except: try: pm.connectAttr(shader.outTransparency, rbf.poseTransparency) except: pass # Build pose rotate locators locX = pm.spaceLocator(n=self.pose[0][0] + '_rotLocX') locY = pm.spaceLocator(n=self.pose[0][0] + '_rotLocY') locZ = pm.spaceLocator(n=self.pose[0][0] + '_rotLocZ') pm.parent(locX, locY, locZ, self.pose[0]) pm.setAttr(locX.translate, (0, 0, 0)) pm.setAttr(locY.translate, (0, 0, 0)) pm.setAttr(locZ.translate, (0, 0, 0)) mult = pm.createNode('multiplyDivide', n='MULTinv_' + self.pose[0][0]) pm.setAttr(mult.operation, 2) pm.setAttr(mult.input1X, 1) pm.setAttr(mult.input1Y, 1) pm.setAttr(mult.input1Z, 1) pm.connectAttr(self.pose[0][0].scale, mult.input2) pm.connectAttr(mult.output, locX.scale) pm.connectAttr(mult.output, locY.scale) pm.connectAttr(mult.output, locZ.scale) mult_neg = pm.createNode('multiplyDivide', n='MULTneg_' + self.pose[0][0]) pm.setAttr(mult_neg.operation, 1) pm.setAttr(mult_neg.input1X, -1) pm.setAttr(mult_neg.input1Y, -1) pm.setAttr(mult_neg.input1Z, -1) pm.connectAttr(rbf.rotateLocatorOffset, locX.tx) pm.connectAttr(rbf.rotateLocatorOffset, locY.ty) pm.connectAttr(rbf.rotateLocatorOffset, locZ.tz) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2X) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2Y) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2Z) pm.connectAttr(mult_neg.outputX, locX.scalePivotX) pm.connectAttr(mult_neg.outputY, locY.scalePivotY) pm.connectAttr(mult_neg.outputZ, locZ.scalePivotZ) pm.connectAttr(locX.worldMatrix[0], rbf.poseRotateLocX) pm.connectAttr(locY.worldMatrix[0], rbf.poseRotateLocY) pm.connectAttr(locZ.worldMatrix[0], rbf.poseRotateLocZ) pm.connectAttr(rbf.rotateLocatorsVisible, locX.visibility) pm.connectAttr(rbf.rotateLocatorsVisible, locY.visibility) pm.connectAttr(rbf.rotateLocatorsVisible, locZ.visibility) pm.setAttr(locX.overrideEnabled, 1) pm.setAttr(locY.overrideEnabled, 1) pm.setAttr(locZ.overrideEnabled, 1) pm.setAttr(locX.overrideColor, 12) pm.setAttr(locY.overrideColor, 23) pm.setAttr(locZ.overrideColor, 29) # Check target list for pose and duplicates if len(self.pose) == 1: single_set = set(self.targets) self.targets = list(single_set) if self.pose[0][0] in self.targets: print "Pose " + self.pose[0][ 0] + " was removed from target list but kept as input pose." self.targets.remove(self.pose[0][0]) # Connect target attrs for i in range(0, len(self.targets)): # Connect target matrix if self.matrix_chk.isChecked() == True: if self.world_rad.isChecked() == True: pm.connectAttr(self.targets[i].worldMatrix[0], rbf.target[i].targetMatrix) else: pm.connectAttr(self.targets[i].parentMatrix[0], rbf.target[i].targetMatrix) # Connect target rbga if self.rgb_chk.isChecked() == True or self.alpha_chk.isChecked( ) == True: shape = pm.listRelatives(self.targets[i], shapes=1)[0] shader_grp = pm.listConnections(shape, type='shadingEngine') shader = pm.listConnections(shader_grp[0], d=0, s=1)[0] if self.rgb_chk.isChecked() == True: try: pm.connectAttr(shader.color, rbf.target[i].targetColor) except: try: pm.connectAttr(shader.outColor, rbf.target[i].targetColor) except: pass if self.alpha_chk.isChecked() == True: try: pm.connectAttr(shader.transparency, rbf.target[i].targetTransparency) except: try: pm.connectAttr(shader.outTransparency, rbf.target[i].targetTransparency) except: pass # Build target rotate locators locX = pm.spaceLocator(n=self.targets[i] + '_rotLocX') locY = pm.spaceLocator(n=self.targets[i] + '_rotLocY') locZ = pm.spaceLocator(n=self.targets[i] + '_rotLocZ') pm.parent(locX, locY, locZ, self.targets[i]) pm.setAttr(locX.translate, (0, 0, 0)) pm.setAttr(locY.translate, (0, 0, 0)) pm.setAttr(locZ.translate, (0, 0, 0)) mult = pm.createNode('multiplyDivide', n='MULTinv_' + self.targets[i]) pm.setAttr(mult.operation, 2) pm.setAttr(mult.input1X, 1) pm.setAttr(mult.input1Y, 1) pm.setAttr(mult.input1Z, 1) pm.connectAttr(self.targets[i].scale, mult.input2) pm.connectAttr(mult.output, locX.scale) pm.connectAttr(mult.output, locY.scale) pm.connectAttr(mult.output, locZ.scale) mult_neg = pm.createNode('multiplyDivide', n='MULTneg_' + self.targets[i]) pm.setAttr(mult_neg.operation, 1) pm.setAttr(mult_neg.input1X, -1) pm.setAttr(mult_neg.input1Y, -1) pm.setAttr(mult_neg.input1Z, -1) pm.connectAttr(rbf.rotateLocatorOffset, locX.tx) pm.connectAttr(rbf.rotateLocatorOffset, locY.ty) pm.connectAttr(rbf.rotateLocatorOffset, locZ.tz) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2X) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2Y) pm.connectAttr(rbf.rotateLocatorOffset, mult_neg.input2Z) pm.connectAttr(mult_neg.outputX, locX.scalePivotX) pm.connectAttr(mult_neg.outputY, locY.scalePivotY) pm.connectAttr(mult_neg.outputZ, locZ.scalePivotZ) pm.connectAttr(locX.worldMatrix[0], rbf.target[i].rotateLocX) pm.connectAttr(locY.worldMatrix[0], rbf.target[i].rotateLocY) pm.connectAttr(locZ.worldMatrix[0], rbf.target[i].rotateLocZ) pm.connectAttr(rbf.rotateLocatorsVisible, locX.visibility) pm.connectAttr(rbf.rotateLocatorsVisible, locY.visibility) pm.connectAttr(rbf.rotateLocatorsVisible, locZ.visibility) pm.setAttr(locX.overrideEnabled, 1) pm.setAttr(locY.overrideEnabled, 1) pm.setAttr(locZ.overrideEnabled, 1) pm.setAttr(locX.overrideColor, 12) pm.setAttr(locY.overrideColor, 23) pm.setAttr(locZ.overrideColor, 29) # Build target alias attrs on RBF node if self.alias_chk.isChecked(): alias = self.targets[i] if '|' in alias: alias = alias.replace('|', '_') pm.aliasAttr(alias, rbf.target[i]) outAlias = alias + 'Out' sigmaAlias = alias + 'Falloff' pm.aliasAttr(outAlias, rbf.outputInterpolate[i]) pm.aliasAttr(sigmaAlias, rbf.outputSigma[i]) pm.getAttr(rbf.outputInterpolate[i]) pm.getAttr(rbf.outputSigma[i]) # Build falloff spheres if self.sigma_chk.isChecked(): bb = pm.xform(self.targets[i], q=1, bb=1) scale = bb[3] - bb[0] ### hard coding sphere radius from trial and error sphere = pm.polySphere(r=5.0, sx=20, sy=20, ax=(0, 1, 0), ch=0, n=str(self.targets[i]) + '_falloff') sphereShp = pm.listRelatives(sphere, s=1) pcon = pm.parentConstraint(self.targets[i], sphere, mo=0) pm.sets(self.sigma_sg, e=1, forceElement=sphereShp) mult = pm.createNode('multiplyDivide', n='MULT_' + self.targets[i] + '_falloff') pm.setAttr(mult.input1X, 0.5) pm.setAttr(mult.operation, 2) pm.connectAttr(rbf.outputSigma[i], mult.input2X) pm.connectAttr(mult.outputX, sphere[0].scaleX) pm.connectAttr(mult.outputX, sphere[0].scaleY) pm.connectAttr(mult.outputX, sphere[0].scaleZ) pm.parent(sphere, self.falloff_group) pm.undoInfo(closeChunk=True) self.close()
def get_selected_attrs(self): """ Get the selected attributes to copy, returning a list of [(input, output)] tuples. For most deformers, this is just the painted weight attribute. If we're copying multiple blend shapes because the source is set to "All", there can be more than one. """ input_deformer = self.input_deformer_list.get_selected_deformer() _, input_deformer_shape_idx = self.input_shape_list.get_selected_shape() output_deformer = self.output_deformer_list.get_selected_deformer() _, output_deformer_shape_idx = self.output_shape_list.get_selected_shape() # Get the selection from the blend shape target dropdowns. selected_input_target can # be '(all)' only if both deformers are blendShapes. selected_input_target = self.input_blend_shape_target_list.get_selected_target() selected_output_target = self.output_blend_shape_target_list.get_selected_target() if isinstance(input_deformer, pm.nodetypes.BlendShape) and selected_input_target == '(all)': assert isinstance(output_deformer, pm.nodetypes.BlendShape), 'Expected the output deformer to be a blendShape, found %s' % output_deformer.nodeType() input_blend_shape_targets = input_deformer.attr('weight') output_blend_shape_targets = output_deformer.attr('weight') # Loop over each available selection, and see if we should add it to the output. input_target = input_deformer.attr('it').elementByLogicalIndex(input_deformer_shape_idx) output_target = output_deformer.attr('it').elementByLogicalIndex(output_deformer_shape_idx) attrs_to_map = [] # Add the main deformer weights. attrs_to_map.append((input_target.attr('bw'), output_target.attr('bw'))) # Make a mapping of blend shape target names to target weights. We'll use this to # match up the names. input_blend_shapes = {pm.aliasAttr(target, q=True): target for target in input_blend_shape_targets} output_blend_shapes = {pm.aliasAttr(target, q=True): target for target in output_blend_shape_targets} for input_name, input_blend_shape in input_blend_shapes.items(): output_blend_shape = output_blend_shapes.get(input_name) if output_blend_shape is None: log.warning('No matching blend shape found for: %s' % input_name) continue log.debug('Mapped blend shape: %s' % (pm.aliasAttr(input_blend_shape, q=True))) input_target_group = input_target.attr('itg').elementByLogicalIndex(input_blend_shape.index()) output_target_group = output_target.attr('itg').elementByLogicalIndex(output_blend_shape.index()) input_weights = input_target_group.attr('targetWeights') output_weights = output_target_group.attr('targetWeights') attrs_to_map.append((input_weights, output_weights)) return attrs_to_map def get_painted_attribute(deformer, selected_target, deformer_shape_idx): if isinstance(deformer, pm.nodetypes.BlendShape): input_target = deformer.attr('it').elementByLogicalIndex(deformer_shape_idx) if selected_target == '(main)': # The first entry in the target list is the weights on the blendShape deformer # itself, which is the first entry in the "Target" list in the blend shape painting # tool. return input_target.attr('bw') input_target_group = input_target.attr('itg').elementByLogicalIndex(selected_target.index()) return input_target_group.attr('targetWeights') else: # Other things are weightGeometryFilters, eg. delta mush and tension deformers. # These only have a single paintable attribute. input_target = deformer.attr('weightList').elementByLogicalIndex(deformer_shape_idx) return input_target.attr('weights') input_attr = get_painted_attribute(input_deformer, selected_input_target, input_deformer_shape_idx) output_attr = get_painted_attribute(output_deformer, selected_output_target, output_deformer_shape_idx) return [(input_attr, output_attr)]
def getNamebyIndex(bsNode, index): weightList = pm.aliasAttr(bsNode, q=True) indexString = [ weightList.index(x) for x in weightList if '[' + str(index) + ']' in x ] return weightList[int(indexString[0]) - 1]
def duplicate_target(self, target_index, name=None): new_index = mel.eval("blendShapeDuplicateTarget {} {};".format(self.bs_node, target_index)) if name is None: name = '{}_DUPLICATE'.format(self.targets[target_index]) pm.aliasAttr(name, '{}.w[{}]'.format(self.bs_node, new_index)) return new_index
if not pm.attributeQuery('weight', n=object_, ex=1): # Check weight data object_ = None if object_ and object_.weight.get() == 1: if base_ and not pm.objExists(blend_name): pm.blendShape(base_, n=blend_name) if str(object_).endswith('target'): new_target_name = object_.replace('_target', '') else: new_target_name = object_ if base_ and pm.objExists(blend_name): pm.blendShape(blend_name, e=1, t=(base_, count_, object_, 1)) blend_attr = pm.PyNode('%s.%s' % (blend_name, object_)) pm.aliasAttr(new_target_name, '%s.w[%s]' % (blend_name, blend_attr.index())) blend_attr = '%s.%s' % (blend_name, new_target_name) check_value(blend_attr, 1.0) count_ += 1 # Loop for in-between target for object_ in list_: parent_ = None if not pm.attributeQuery('weight', n=object_, ex=1): # Check weight data object_ = None if pm.attributeQuery('parent', n=object_, ex=1): # Check parent data
import pymel.core as pymel """Cycles through shapes in Face_Blnd node and renders out playblasts""" """CONSTANTS""" blendName = pymel.aliasAttr('Face_Blnd', query=True) time = pymel.currentTime() #path = pymel.mel.eval('getenv "AVATARS_V3_PERFORCE_DEPOT"') path = 'C:/Users/v-nebera/Desktop/strips_test' timeline_length = 200 ctrl_grp = pymel.PyNode('Ctrls_Grp') def cycle_though_body_shape(): for i in ctrl_grp.Proportion.getEnums(): ctrl_grp.Proportion.set(i) screen_shot(i) def cycle_blendshapes(reset=True): for i in range(len(blendName) / 2): target_name = blendName[(i * 2)] if check_target(target_name): if reset: print "reset!" pymel.setAttr('Face_Blnd.' + target_name, 0) else: screen_shot(target_name) if reset:
def getIndexByName(bsNode, targetName): weightList = pm.aliasAttr(bsNode, q=True) nameIndex = weightList.index(targetName) bsIndex = re.split('\[(.*?)\]', str(weightList[nameIndex + 1])) return int(bsIndex[1])
def _refresh_dropdowns(self): # Make a list of outputs. The output list is sparse and the dropdown box isn't, # so keep track of both output indices and list indices. selection_names = [] for output in self.weight_node.attr('output'): connected_attrs = output.listConnections(s=False, d=True, p=True) if not connected_attrs: continue connected_attr = connected_attrs[0] connected_name = pm.aliasAttr(connected_attr, q=True) if not connected_name: connected_name = connected_attr.plugAttr(longName=True) selection_names.append({ 'name': connected_name, 'output_index': output.index(), }) if not selection_names: self.ui.controls.setVisible(False) self.ui.noOutputs.setVisible(True) return else: self.ui.controls.setVisible(True) self.ui.noOutputs.setVisible(False) # The outputs are typically in an arbitrary order, so sort them. selection_names.sort(key=lambda item: item['name'].lower()) self.selection_names = selection_names # If the current choice isn't actually connected, add an entry for it. choice1_shape_idx = self.weight_node.attr('choice1').get() choice2_shape_idx = self.weight_node.attr('choice2').get() choice1 = self.get_list_index_from_output_idx(choice1_shape_idx) choice2 = self.get_list_index_from_output_idx(choice2_shape_idx) if choice1 == -1: choice1 = len(selection_names) selection_names.append({ 'name': '(unknown shape #%i)' % choice1_shape_idx, 'output_index': choice1, }) if choice2 == -1 and choice1_shape_idx == choice2_shape_idx: # Both shapes are set to the same disconnected shape. choice2 = choice1 elif choice2 == -1: choice2 = len(selection_names) selection_names.append({ 'name': '(unknown shape #%i)' % choice2_shape_idx, 'output_index': choice2, }) self.ui.shapeSelection1.clear() self.ui.shapeSelection2.clear() for item in selection_names: self.ui.shapeSelection1.addItem(item['name']) self.ui.shapeSelection2.addItem(item['name']) self.ui.shapeSelection1.setCurrentIndex(choice1) self.ui.shapeSelection2.setCurrentIndex(choice2)