def rig_ctrlDuplicate(ctrl, name): """Creates a hub set Args: ctrl (pm.PyNode): maya objects to rename name (str): new name Returns: list: [offset_grp, ctrl, con_grp] """ orig_name = ctrl.split('_')[0] grp_offset,grp_con = None,None if str(ctrl.getParent()) == orig_name+'Offset_GRP': grp_offset = pm.PyNode(orig_name + 'Offset_GRP') if orig_name+'Con_GRP' in ctrl.getChildren(): grp_con = pm.PyNode(orig_name+'Con_GRP') if grp_offset: grp_offsetDup = pm.duplicate(grp_offset,n=name+'Offset_GRP',po=True) ctrl_dup = pm.duplicate(ctrl,n=ctrl.replace(orig_name, name)) ctrl_dup[0].setParent(grp_offsetDup) for child in ctrl_dup[0].getChildren(): if child.type() != 'nurbsCurve': pm.delete(child) if grp_con: grp_conDup = pm.duplicate(grp_con,n=name+'Con_GRP',po=True) grp_conDup[0].setParent(ctrl_dup) if grp_offset: return [grp_offsetDup[0],ctrl_dup[0],grp_conDup[0]] else: return [None,ctrl_dup[0],grp_conDup[0]]
def clear(self): """ Method: clear A method to delete all of the maya objects generated by the joint chain """ if self.m_isGenerated == True: #delete maya objects for jnt in self.m_joints: try: pm.delete(jnt) except: pass #then reset the list self.m_joints = [] #and set the is generated boolean self.m_isGenerated = False """--------------------"""
def __armFK__(self, shoulder): self.armFk = self.__armPlaceJnt__(parent=self.gp['arm'], prefix='fk') # create controlor for i in range(len(self.armFk)): # put a better rotate order self.armFk[i].rotateOrder.set(3) # add shape to joint tmp = arShapeBiblio.cube(name=self.armFk[i], color=self.colorOne) pmc.parent(tmp.getShape(), self.armFk[i], shape=True, relative=True) pmc.delete(tmp) # scale shape if i < (len(self.armFk)-1): arShape.scaleShape(self.armFk[i].getShape(), self.armFk[i], self.armFk[i+1]) # clean channel box self.armFk[i].rotateOrder.setKeyable(True) clean.__lockHideTransform__(self.armFk[i], channel=['t', 'v', 'radi']) # add attribut for the first fk bone attribut.addAttrSeparator(self.armFk[0]) # ADD CONSTRAINT ORIENT # pickwalk chain = [shoulder] chain.extend(self.armFk[0:-1]) arPickwalk.setPickWalk(chain, type='UD') return {self.mainSets:self.armFk}
def delete_system(self): if self.delete == True: pm.delete(self.main_group) self.kill() if self.delete == False: self.kill()
def buildMainControls(self): # Get the ctrl postion ctrlPosition = utils.recalculatePosition(self.jointSystem.positions, self.numHighLevelCtrls) metaCtrls = [] # Iterate though all the position for i in range(self.numHighLevelCtrls): output_window("Build Main Control: {}".format(i)) # Create a control object ctrl = self.createCtrlObj("%s%i" % (self.part, i)) # Set the position ctrl.prnt.translate = list(ctrlPosition[i]) # Lock the scale ctrl.lockScale() metaCtrls.append(ctrl) # Is orientation set to world if not self.ikControlToWorld: # Get the closest joint position closestJoints = libMath.spread(0, len(self.jointSystem) - 1, self.numHighLevelCtrls) for jointPosition, i in zip(closestJoints, range(self.numHighLevelCtrls)): # Is a closest joint a fraction if jointPosition % 1: # Orient between current and next pm.delete(pm.orientConstraint( self.jointSystem.jointList[int(jointPosition)], self.jointSystem.jointList[int(jointPosition) + 1], metaCtrls[i].prnt.pynode)) else: pm.delete(pm.orientConstraint( self.jointSystem.jointList[int(jointPosition)], metaCtrls[i].prnt.pynode)) self.mainCtrls = metaCtrls
def deleteGuides(self): """ THis function deletes the guides from the scene WILL BE CHANGED LATER WHEN WE EXPAND """ pm.delete(self.guidesGrp)
def createEmitter(self, mesh, name="particleEmitter_msh"): # Create boundingBox of the mesh bbx = pm.polyEvaluate(mesh, b=True) cube = pm.polyCube( w=abs(bbx[0][1] - bbx[0][0]), h=abs(bbx[1][1] - bbx[1][0]), d=abs(bbx[2][1] - bbx[2][0]), sx=1, sy=1, sz=1, ax=(0, 1, 0), cuv=4, ch=0, name=name, ) cube = cube[0] cube.setAttr("t", ((bbx[0][1] + bbx[0][0]) / 2, (bbx[1][1] + bbx[1][0]) / 2, (bbx[2][1] + bbx[2][0]) / 2)) # Keep only face 1 for emit pm.delete([cube + ".f[2:6]", cube + ".f[0]"]) # Connection of mesh and the emitter self.connectOriginaleMesh(mesh, cube) # Move emitter in y in a percentage of area of face. face = pm.PyNode(cube + ".f[1]") area = face.getArea(space="world") pm.select(cube) y = pow(area, 0.1) * 100 pm.move(0, y, 0, r=1, os=1, wd=1) return cube
def edgeFlow(self): oldSel = pm.ls(sl = 1) pm.select(pm.ls(o=1, sl=1)) selected = pm.ls(sl = 1) pm.delete(selected, constructionHistory = 1) pm.select(cl = 1) for s in selected: rootEdges = pm.ls( self.root(s) , fl = 1) tipEdges = pm.ls( self.tip(s) , fl = 1) ############length edgeloops of the card myEdges = pm.ls(pm.polySelect(s, ebp = [ rootEdges[0].index(), tipEdges[0].index() ],ass = True ), fl = 1) side1Edges = [x for x in myEdges if x not in rootEdges and x not in tipEdges] borderEdges = [x for x in pm.ls(s.e, fl = 1) if x.isOnBoundary()] pm.select(tipEdges) for x in range(len(side1Edges)*2): if x != borderEdges and x!= rootEdges and x!= tipEdges: pm.polyEditEdgeFlow(adjustEdgeFlow=1, constructionHistory=0) pm.pickWalk(type = 'edgeloop', direction = 'left') if self.lenCheckBox.getValue() == 1: pm.select(side1Edges) for x in range( len(rootEdges)*2 ): pm.polyEditEdgeFlow(adjustEdgeFlow=1, constructionHistory=0) pm.pickWalk(type = 'edgeloop', direction = 'left') pm.select(oldSel)
def rebuildDagPose(): """ Walks through bind pose data in selected skeleton and consolidates it down to one new bindPose node Directly inspired by Nathan Horne's NT_rebuildDagPose.mel script """ dagPoses = set() connectedSkinClusters = set() selection = pmc.selected() joints = pmc.listRelatives(selection[0], path=True, allDescendents=True, type="joint") joints.insert(0, selection[0]) for jnt in joints: dagPoses.update(jnt.listConnections(type="dagPose")) for dag in dagPoses: connectedSkinClusters.update(dag.listConnections(type="skinCluster")) pmc.delete(dagPoses) pmc.select(joints, replace=True) newDagPose = pmc.dagPose(save=True, selection=True, bindPose=True) print "New dagPose, {0}, created".format(newDagPose.shortName()) for sc in connectedSkinClusters: print "Connecting {0}.message to {1}.bindPose".format(newDagPose.shortName(), sc.shortName()) newDagPose.message.connect(sc.bindPose)
def _delConstraints(self, jnt, *args): pm.select(jnt, hi=1, r=1) sel = pm.ls(sl=1) consList = ['parentConstraint','scaleConstraint','orientConstraint', 'pointConstraint'] for each in sel: for cons in consList: if each.type() == cons: pm.delete(each)
def getMirrorAttrDrivenCurve(animUL): driverName, driverAttr, drivenName, drivenAttr = getDrivenName(animUL) mirrorDriver = getMirrorCtrl(pm.PyNode(driverName)) mirrorDriven = getMirrorCtrl(pm.PyNode(drivenName)) mirrorAnimUL = getAttrDrivenCurve(mirrorDriver, driverAttr, mirrorDriven, drivenAttr) if mirrorAnimUL: pm.delete(mirrorAnimUL) mirrorAnimULName = "{driver}_{driverAttr}_to_{driven}_{drivenAttr}".format(driver=mirrorDriver.name(), driverAttr=driverAttr, driven=mirrorDriven.name(), drivenAttr=drivenAttr) mirrorAnimUL = pm.createNode("animCurveUL", name = mirrorAnimULName) mfnAnimUL = mirrorAnimUL.__apimfn__() for i in range(animUL.numKeys()): input = animUL.getUnitlessInput(i) value = animUL.getValue(i) if driverAttr == 'tx' and drivenAttr == 'tx': if input != 0: newInput = -1*input newValue = -1*value elif driverAttr == 'tx' and drivenAttr != 'tx': if input != 0: newInput = -1*input newValue = value else : newInput = input newValue = value mfnAnimUL.addKey(newInput, newValue, 1, 1) return mirrorAnimUL
def import_hierarchy_geo(self): """Import all the obj objects""" file_info = self.geo_file_info for self.current_target in file_info.keys(): cmds.file(file_info[self.current_target], rpr="PKD_Temp", i=1, type="OBJ", loadReferenceDepth="all", ra=True, mergeNamespacesOnClash=False, options="mo=1") # Delete Existing geo if it exists if not self.cleansing_mode: if pm.objExists(self.current_target): pm.delete(self.current_target) logger.info("Importing\n%s" % file_info[self.current_target]) if self.cleansing_mode: os.remove(file_info[self.current_target]) for top in pm.ls(assemblies=True, ud=True): if top.getShape(): if top.getShape().type() == "mesh" and top.name() == "PKD_Temp_Mesh": top.rename(self.current_target) pm.select(self.current_target) mel.eval("polySetToFaceNormal") mel.eval("polySoftEdge -a 180 -ch 1 %s" % self.current_target) pm.delete(self.current_target, ch=1) pm.refresh() self.update_progress()
def create_point_on_mesh(geo, position, sticky_target, free_rotation=True): """ Create point on mesh setup @param position: @param geo: @parem sticky: @return: """ pom = pm.createNode("closestPointOnMesh") pom.inPosition.set(position) geo.worldMatrix[0] >> pom.inputMatrix geo.worldMesh[0] >> pom.inMesh pom.position >> sticky_target.translate index = pom.closestVertexIndex.get() locator = pm.spaceLocator() libUtilities.snap(locator, geo.vtx[index], rotate=False) libUtilities.freeze_transform(locator) pm.pointOnPolyConstraint(geo.vtx[index], locator, maintainOffset=True) pm.delete(pom) constraint = pm.listRelatives(locator, type="constraint")[0] if free_rotation: for attr in ["rx", "rz", "ry"]: libUtilities.break_connection(locator, attr) locator.attr(attr).set(0) return {"constraint": constraint, "locator": locator}
def __transformToBone__(obj): name = obj.name() # create joint jnt = pmc.createNode('joint', name=name+'_') # set parent if obj.getParent(): jnt.setParent(obj.getParent()) # set transformation jnt.setTranslation(obj.getTranslation(space='object'), space='object') jnt.setRotationOrder(obj.getRotationOrder(), reorder=True) jnt.jointOrientX.set(obj.getRotation(space='object')[0]) jnt.jointOrientY.set(obj.getRotation(space='object')[1]) jnt.jointOrientZ.set(obj.getRotation(space='object')[2]) jnt.setScale(obj.getScale()) jnt.setShear(obj.getShear()) # get children children = obj.getChildren() for child in children: child = various.checkObj(child, type=['transform', 'joint'], echo=False) if child: child.setParent(jnt) # parent shape if obj.getShape(): pmc.parent(obj.getShape(), jnt, shape=True, relative=True) # deleting and renaming properly pmc.delete(obj) jnt.rename(name) return jnt
def export_hierarchy_obj(self): """Export the individual meshes in the hierarchy""" file_info = {} # Reverse the geo list so that the deepest geo is deleted first in case there is a geo inside geo geo_list = self.geo_list geo_list.reverse() for self.current_target in geo_list: pm.delete(self.current_target, ch=1) parent = pm.listRelatives(self.current_target, parent=True) pm.parent(self.current_target, w=True) pm.select(self.current_target) path = libFile.linux_path(libFile.join(self.export_dir, self.current_target + ".obj")) # Load the obj plugin cmds.file(path, pr=1, typ="OBJexport", force=1, options="groups=0;ptgroups=0;materials=0;smoothing=0;normals=0", es=1) file_info[self.current_target] = path logger.info("Exporting\n%s" % file_info[self.current_target]) if not self.new_scene and self.cleansing_mode: pm.delete(self.current_target) pm.refresh() else: pm.parent(self.current_target, parent) self.update_progress() # Write the geo file_info self.geo_file_info = file_info
def AlignBindNode(self, **kws): ''' Overwrite the default behaviour: Align the newly made BindNode as required for this bind ''' parentNode = self.SourceNode.listRelatives(p=True)[0] if parentNode: #Parent the BindNode to the Source Driver Node pm.parent(self.BindNode['Root'], self.SourceNode.listRelatives(p=True)[0]) else: pm.parent(self.BindNode['Root'], self.SourceNode) self.BindNode['Main'].rotateOrder.set(self.SourceNode.rotateOrder.get()) self.BindNode['Root'].rotateOrder.set(self.DestinationNode.rotateOrder.get()) #Positional Alignment if self.Settings.AlignToControlTrans: pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.DestinationNode, self.BindNode['Root'])) if self.Settings.AlignToSourceTrans: pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) #Rotation Alignment if parentNode: pm.orientConstraint(self.SourceNode, self.BindNode['Root']) if self.Settings.AlignToControlRots: pm.delete(pm.orientConstraint(self.DestinationNode, self.BindNode['Main'])) if self.Settings.AlignToSourceRots: pm.delete(pm.orientConstraint(self.SourceNode, self.BindNode['Main']))
def AlignBindNode(self, **kws): ''' Overwrite the default behaviour: Align the newly made BindNode as required for this bind ''' #Parent the BindNode/UpVector Object to the upVectorParent Node #Parent the AimLocator Object to the Source node -used to modify the AimPoint pm.parent(self.BindNode['Root'], self.upVectorParent) pm.parent(self.BindNode['Up'], self.upVectorParent) pm.parent(self.BindNode['AimOffset'], self.SourceNode) #self.BindNode['Root'].scale.set(self.Settings.BaseScale,self.Settings.BaseScale,self.Settings.BaseScale) self.BindNode['Main'].rotateOrder.set(self.SourceNode.rotateOrder.get()) self.BindNode['Root'].rotateOrder.set(self.DestinationNode.rotateOrder.get()) #Aim Alignment pm.aimConstraint(self.BindNode['AimOffset'], self.BindNode['Root'], aimVector=(0,1,0),upVector=(0,0,1),\ worldUpType="object",worldUpObject=self.BindNode['Up']) #Positional Alignment pm.delete(pm.pointConstraint(self.SourceNode, self.BindNode['AimOffset'])) pm.makeIdentity(self.BindNode['AimOffset'], apply=True, t=1, r=1, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Root'])) pm.makeIdentity(self.BindNode['Root'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.upVectorParent, self.BindNode['Up'])) pm.makeIdentity(self.BindNode['Up'], apply=True, t=1, r=0, s=0) pm.delete(pm.pointConstraint(self.DestinationNode, self.BindNode['Root'])) #Rotate Alignment pm.delete(pm.orientConstraint(self.DestinationNode, self.BindNode['Main']))
def createBendDeformerOnCurve(curveTransforms, upDir=(1,0,0), aimDir=(0,1,0)): '''Creates bend deformers on every curve and aims them at the end Args: curveTransforms ([pm.nt.Transform]): list of transforms with nurbsCurve shapes upDir (float, float, float): up direction for aim to orient the bend deformer Returns: ([pm.nt.nonLinear]): list of bend deformers Usage: createBendDeformerOnCurve(pm.ls(sl=True)) ''' bends=[] for curveTransform in curveTransforms: bendName = curveTransform.name().replace('CRV','BEND') bend = pm.nonLinear(curveTransform, type='bend', frontOfChain=True, curvature=0.0, lowBound=0, highBound=1) bend[0].rename(bendName.replace('BEND','BENDHDL')) bend[1].rename(bendName) startPosition = curveTransform.getShape().cv[0].getPosition(space='world') endPosition = curveTransform.getShape().cv[-1].getPosition(space='world') loc = pm.spaceLocator() pm.move(loc, endPosition, a=True) pm.move(bend[1], startPosition, a=True) aimConst = pm.aimConstraint( loc, bend[1], upVector=upDir, aimVector=aimDir ) pm.delete([loc, aimConst]) bends.append(bend) return bends
def buildIK(self, *args): """ Build the IK """ #Setup variables if self.normal == 1: self.normal = (1, 0, 0) if self.normal == 2: self.normal = (0, 1, 0) if self.normal == 3: self.normal = (0, 0, 1) #Create IK control self.ikControl = pm.circle(nr=self.normal, r=self.radius, n='%s_ikCnt'%self.prefix) pm.select(self.ikControl[0], r=True) pm.mel.eval("DeleteHistory;") pm.delete( pm.parentConstraint(self.ikChain[2], self.ikControl[0], mo=0) ) self.zero(self.ikControl[0]) #Create RP IK self.arm_ikHandle = pm.ikHandle(sj=self.ikChain[0], ee=self.ikChain[2], solver='ikRPsolver', name=(self.prefix + '_armIkHandle')) pm.setAttr(self.arm_ikHandle[0] + '.visibility', 0) #Parent IK Handle to the ikWrist_cnt pm.parent(self.arm_ikHandle[0], self.ikControl[0]) # Creates: self.pv_cnt self.createPoleVector()
def carBodyFix(): constraints=['l_frontDoorOffset_GRP_parentConstraint1', 'r_frontDoorOffset_GRP_parentConstraint1', 'l_rearDoorOffset_GRP_parentConstraint1', 'r_rearDoorOffset_GRP_parentConstraint1', 'frontBumperOffset_GRP_parentConstraint1', 'hoodOffset_GRP_parentConstraint1', 'rearBumperOffset_GRP_parentConstraint1', 'antennaOffset_GRP_parentConstraint1', 'trunkOffset_GRP_parentConstraint1', 'l_wiperOffset_GRP_parentConstraint1', 'r_wiperOffset_GRP_parentConstraint1'] pm.delete(constraints) groups = ['r_wiperOffset_GRP', 'l_wiperOffset_GRP', 'trunkOffset_GRP', 'antennaOffset_GRP', 'rearBumperOffset_GRP', 'hoodOffset_GRP', 'frontBumperOffset_GRP', 'r_rearDoorOffset_GRP', 'l_rearDoorOffset_GRP', 'r_frontDoorOffset_GRP', 'l_frontDoorOffset_GRP'] for group in groups: pm.parentConstraint('bodyJA_JNT', group, mo=True)
def createHighlight(mesh, lightType=mayaLights["Spot"], offset=6): """ Create Light based on curve drawn on object """ # Get the currently selected curve curveA = getSelection() # Get the start and end points of the curve as Vectors crv_posA = dt.Vector(pm.pointOnCurve(curveA, pr=0)) crv_posB = dt.Vector(pm.pointOnCurve(curveA, pr=curveA.maxValue.get())) # Calculate the mid point midPoint = (crv_posA + crv_posB) / 2 # Get closest point & normal on mesh pointOnMesh_set = mesh.getClosestPointAndNormal(midPoint, space="world") pointOnMesh = pointOnMesh_set[0] pointOnMesh_normal = pointOnMesh_set[1] pm.spaceLocator(p=pointOnMesh) # For debug/vis # Create dummy camera cam = pm.camera() camera = cam[0] camera.setTranslation(pointOnMesh + pointOnMesh_normal * offset) pm.viewLookAt(camera, pos=pointOnMesh) # Create light createLight(lightType, camera.getTranslation(), camera.getRotation()) # Delete dummy camera pm.delete(camera)
def loadTranslationControl(root_joint, module_name, container, module_control_grp, control_type = "translation", color = [1, 0, 0]): """ loads translation control onto the root_joint """ path = os.path.join(environ.ControlObjectsPath, "translation_control.ma") pm.importFile(path, renameAll = True, loadReferenceDepth = "all", namespace =":") # renamePrefix == namespace # rename default module translation_control = pm.rename("translation_control", module_name + ":" + root_joint.stripNamespace() + "_translation_control", ignoreShape = False) translation_control_grp = pm.group(translation_control, name = module_name + ":" + root_joint.stripNamespace() + "_translation_controlGrp") # move control to root root_joint pm.delete(pm.pointConstraint(root_joint, translation_control_grp, maintainOffset=False)) translation_control_grp.setParent(module_control_grp) pm.addAttr(translation_control, longName="ControlType", dataType="string", keyable=False) pm.addAttr(translation_control, longName="ParentObject", at="message", multi = True) translation_control.ControlType.set(control_type, type = "string", lock = True) utils.addNodeToContainer(container, [translation_control, translation_control_grp], ihb = True, includeNetwork = True) pm.container(container, edit=True, publishAndBind=[translation_control + ".rotate", translation_control.stripNamespace() + "_rotate"]) pm.container(container, edit=True, publishAndBind=[translation_control + ".translate", translation_control.stripNamespace() + "_translate"]) return translation_control, translation_control_grp
def bdLocOnJnt(): try: rootJnt = pm.ls(sl=True)[0] except: pm.warning('Nothing selected') return try: crvPath = pm.ls(sl=True)[1] except: pm.warning('No curve selected') return allJnt = rootJnt.listRelatives(f=True, ad=True,type='joint') allJnt = allJnt + [rootJnt] allJnt.reverse() locators = [] for jnt in allJnt: print jnt loc = pm.spaceLocator(name = jnt.name().replace( '_jnt','_loc')) locGrp = pm.group(n = loc.name() + '_grp') tempCnstr = pm.pointConstraint(jnt,locGrp,mo=0); pm.delete(tempCnstr ) locators.append(locGrp) bdMultiMotionPath(crvPath, locators) bdParentJntToLocs(allJnt)
def position_joint(self): ''' # positions the joint ''' temp_parent_constraint = pm.parentConstraint(self.bound_geo, self.joint, maintainOffset= False) pm.delete(temp_parent_constraint)
def bdAddExtraGrp(nameMaskCon,grpType,empty): controllers = pm.ls(nameMaskCon,type = 'transform') conPyNodes = [] for con in controllers: conPyNodes.append(con) for node in conPyNodes: if empty: pm.select(cl=True) conGrp = pm.group(name = node.name() + '_' + grpType) pos = node.getTranslation(space='world') rot = node.getRotation(space='world') conGrp.setTranslation(pos) conGrp.setRotation(rot) parent = node.getParent() pm.parent(conGrp,parent) else: conGrp = pm.duplicate(node,name = node.name().replace('CON',grpType)) ''' for axis in ['X','Y','Z']: conGrp[0].attr('translate' + axis).setKeyable(True) conGrp[0].attr('translate' + axis).setLocked(False) ''' conGrpRelatives = pm.listRelatives(conGrp,ad = True) #print sdkConRelatives pm.delete(conGrpRelatives) pm.parent(node,conGrp)
def checkTwoSkin(cls, skin_from, skin_to): """ !@Brief Check two skin. If skin_to is different of skin_from delete it and apply new skin with same influences of skin_from. :type skin_from: pymel.core.nodetypes.SkinCluster :param skin_from: Skin reference for check :type skin_to: pymel.core.nodetypes.SkinCluster :param skin_to: Skin you want to check :rtype: pymel.core.nodetypes.SkinCluster :return: SkinCluster checked """ # Get influences influences_ref = pmc.skinCluster(skin_from, query=True, influence=True) influences_check = pmc.skinCluster(skin_to, query=True, influence=True) # If is same return check skinCluster if influences_check == influences_ref: return skin_to # If is not same apply new skin skin_check_geo = pmc.skinCluster(skin_to, query=True, geometry=True) pmc.delete(skin_to) for geo in skin_check_geo: skin_to = cls.skinFromOther(skin_from, geo) return skin_to
def removeBindPose(cls, skin_node): """ !@Brief Remove BindPose of SkinCluster :rtype: bool :return: True if bindPose is deleted """ # Check if isinstance(skin_node, basestring): skin_node = pmc.PyNode(skin_node) if isinstance(skin_node, pmc.nodetypes.SkinCluster): raise RuntimeError("\n\tThis node -- %s -- is not a SkinCluster !!!\n" % skin_node.name()) # Get BindPose bindpose_node = self.SKIN_NODE.inputs(type='dagPose') if not bindpose_node: raise RuntimeError("\n\tSkinCluster doesn't have bindPose !!!\n") # Remove pmc.delete(bindpose_node) return True
def _parentSurfaceFLCL(self, constrained_obj, geo, deleteCPOMS=1): """ Parents object to follicle at closest point on surface. Select child transform, then select mesh to hold parent follicle. """ cpos = pmc.createNode('closestPointOnSurface', n='cpos_flcl_' + geo) mc.connectAttr(pmc.listRelatives(geo, shapes=True, children=True)[0] + '.local', cpos + '.inputSurface') obj_mtx = pmc.xform(constrained_obj, q=True, m=True) pmc.setAttr(cpos + '.inPosition', [obj_mtx[12], obj_mtx[13], obj_mtx[14]]) flclShape = pmc.createNode('follicle', n='flclShape' + geo) flcl = pmc.listRelatives(flclShape, type='transform', parent=True) pmc.rename(flcl, 'flcl_' + geo + '_1') mc.connectAttr(flclShape + '.outRotate', flcl[0] + '.rotate') mc.connectAttr(flclShape + '.outTranslate', flcl[0] + '.translate') mc.connectAttr(geo + '.worldMatrix', flclShape + '.inputWorldMatrix') mc.connectAttr(geo + '.local', flclShape + '.inputSurface') mc.setAttr(flclShape + '.simulationMethod', 0) u = mc.getAttr(cpos + '.result.parameterU') v = mc.getAttr(cpos + '.result.parameterV') pmc.setAttr(flclShape + '.parameterU', u) pmc.setAttr(flclShape + '.parameterV', v) pmc.parent(constrained_obj, flcl) if deleteCPOMS == 1: pmc.delete(cpos) return flcl
def duplicate_rigid_body(self): self.bound_geo = pm.duplicate(self.rigid_body, name= '%s_rb' % (self.rigid_body))[0] shape_nodes = self.bound_geo.getShapes() for shape_node in shape_nodes: if 'rigidBody' in '%s' % (shape_node): pm.delete(shape_node)
def rtb_remove(highresListDropdown, *args, **kwargs): ''' remove item from the list and delete live-mesh and groups ''' global defaultString high = highresListDropdown.getValue() if not high == defaultString: high = pm.PyNode(high.split("'")[0]) #get rid of unicode crap high.rename(high.rstrip('_high')) pm.parent(high, world=True) high.setScale([1,1,1]) pm.disconnectAttr('persp.translate', high.scalePivot) if pm.displaySurface(high, query=True, xRay=True)[0] == True: pm.displaySurface(high, xRay=False) if not high.visibility.get(): high.visibility.set(True) highShape = high.getShape() highShape.overrideDisplayType.set(0) #sets to normal mode highShape.overrideEnabled.set(0) #disable display overrides pm.delete(str(high)+'_RETOPO') rtb_highres_list_populate(highresListDropdown)
def plane_proxy(joints_chain, name , axis = 'z', scale = 1, type = 'mesh'): """ Create a plane proxy for a joint chain @param joints_chain: list. List of the joints from which to create a curve @param name: String. Name of the final plane proxy @param axis: String {'x','y' or 'z'} NOTES!! : The joint chain need to be proprely oriented ## EXTERIOR CLASS BUILD #------------------------ import adb_utils.adb_script_utils.Script__ProxyPlane as adbProxy reload (adbProxy) Proxy_plane = adbProxy.plane_proxy(pm.selected(), 'adb', 'z') """ all_xmax_locs = [] all_xmin_locs = [] all_loc_groups = [] def createLocs(subject): loc_align = pm.spaceLocator() pm.matchTransform(loc_align,subject, rot=True, pos=True) loc_align.sx.set(scale) loc_align.sy.set(scale) loc_align.sz.set(scale) return loc_align def createCurve(pos ,curve_name): knot = [] for i in range(len(joints_chain)): knot.append(i) _curve= pm.curve(p = pos, k =knot, d=1, n=curve_name) # pm.rebuildCurve(_curve, rt=0, ch=0, end=1, d=3, kr=0, s=len(joints_chain), kcp=0, tol=0.1, kt=0, rpo=1, kep=1) return _curve starting_locs = [createLocs(x) for x in joints_chain] for each in starting_locs: posBox = adbBBox.Bbox([each]) posLocs = posBox.createPosLocs() posLocs_grp = pm.group(posLocs, n= '{}__grp__'.format(each) ) all_loc_groups.append(posLocs_grp) pm.xform(posLocs_grp, cp=True) pm.matchTransform(posLocs_grp, each, pos=True, rot=True) if axis == 'y': max_value = posLocs[1] all_xmax_locs.append(max_value) min_value = posLocs[4] all_xmin_locs.append(min_value) elif axis == 'x': max_value = posLocs[3] all_xmax_locs.append(max_value) min_value = posLocs[0] all_xmin_locs.append(min_value) elif axis == 'z': max_value = posLocs[-1] all_xmax_locs.append(max_value) min_value = posLocs[2] all_xmin_locs.append(min_value) pos_locs_xmax = [createLocs(x) for x in all_xmax_locs] all_xmax_values = [x.getTranslation() for x in pos_locs_xmax] pos_locs_xmin = [createLocs(x) for x in all_xmin_locs] all_xmin_values = [x.getTranslation() for x in pos_locs_xmin] curve1 = createCurve(all_xmax_values, 'max_curve') curve2 = createCurve(all_xmin_values, 'min_curve') if type == 'mesh': nurbs_plane = pm.loft(curve1, curve2, c=0, ch=0, reverseSurfaceNormals = True, d=1, ar=1, u=1, rn=1, po=0)[0] plane_msh = pm.nurbsToPoly(nurbs_plane, n=name, uss=1, ch=0, ft=0.01, d=0.1, pt=1, f=2, mrt=0, mel=0.001, ntr=0, vn=1, pc=100, chr=0.1, un=len(pm.PyNode(curve2).getShape().getCVs()), vt=1, ut=1, ucr=0, cht=0.2, mnd=1, es=0, uch=0)[0] pm.delete(nurbs_plane) elif type == 'nurbs': pm.rebuildCurve(curve1, rt=0, ch=0, end=1, d=3, kr=0, s=len(joints_chain), kcp=0, tol=0.1, kt=0, rpo=1, kep=1) pm.rebuildCurve(curve2, rt=0, ch=0, end=1, d=3, kr=0, s=len(joints_chain), kcp=0, tol=0.1, kt=0, rpo=1, kep=1) plane_msh = pm.loft(curve1, curve2, n=name, c=0, ch=0, reverseSurfaceNormals = True, d=1, ar=1, u=1, rn=1, po=0)[0] mc.DeleteHistory(plane_msh) mc.CenterPivot(plane_msh) ## cleanUp pm.delete(starting_locs, all_loc_groups, pos_locs_xmax, pos_locs_xmin) pm.delete(curve1) pm.delete(curve2) return plane_msh # plane_proxy(pm.selected(), 'proxy' , axis = 'x', type = 'mesh')
import raven.rigLib.transform as tr reload(rig) reload(tr) # 모듈 인스턴스 생성 head = rig.Head() # 조인트 생성 head.createJoint() # 레이아웃 생성 head.createLayout() # 레이아웃 삭제 pm.delete(head.layout.parent) # 레이아웃 재 생성 head.createLayout() # 위치 조정 head.layout.root.t.set(0, 0, 0) head.layout.root.r.set(0, 0, 0) # 눈 인스턴스 생성 leftEye = rig.Eye('L') # 눈 조인트 생성 leftEye.createJoint() # 조인트 레이아웃 생성
def start_optimize_fbx(self, export_files): """ 优化FBX文件 主要功能: 1.清除命名空间 2.清理头部的动画曲线 :param export_files: 需要输出的文件列表 :return: True """ # export_grp = ["character_root", "final_model_grp"] system_namespace = ['UI', 'shared'] for export_file in export_files: # 新建场景,打开指定场景 cmds.file(new=True, force=True) cmds.file(export_file, o=True) file_name = cmds.file( q=1, sceneName=True, shortName=True).split('.')[0] print(file_name + ' already open!') # 将MAYA的时间格式改成ntsc(30帧每秒) common.set_time_unit(unit='ntsc') # 命名空间列表 all_namespace_list = pm.namespaceInfo(lon=True) for name in system_namespace: all_namespace_list.remove(name) # 清楚命名空间 for namespace in all_namespace_list: pm.namespace(removeNamespace=":%s" % namespace, mergeNamespaceWithParent=True) if pm.objExists("character_Group"): pm.delete("character_Group") # 清理头部动画 if pm.checkBoxGrp(self.fbx_optimize, q=True, v1=True): pm.select("head_JNT", hi=True) for jnt in pm.ls(sl=True): anim_attrs = pm.listAttr(jnt, k=True) for anim_attr in anim_attrs: cmd = '''cutKey -cl -t ":" -f ":" -at %s %s;''' % ( anim_attr, jnt.controller_name()) mel.eval(cmd) # 清理指定骨骼的动画 if pm.checkBoxGrp(self.fbx_optimize, q=True, v2=True): target_joint = pm.textFieldGrp( self.optimize_target, q=True, text=True) if pm.objExists(target_joint): # pm.select(target_joint) anim_attrs = pm.listAttr(target_joint, k=True) for anim_attr in anim_attrs: cmd = '''cutKey -cl -t ":" -f ":" -at %s %s;''' % ( anim_attr, target_joint) mel.eval(cmd) offset_value = pm.floatFieldGrp( self.offset_target, q=True, value=True) pm.PyNode(target_joint).translate.set(offset_value) export_file_name = "%s/%s.fbx" % (self.output_path, file_name) # 清理模型组 if pm.checkBoxGrp(self.fbx_optimize, q=True, v3=True): if pm.objExists("MotionSystem"): pm.delete("MotionSystem") if pm.objExists("Geometry"): pm.delete("Geometry") if len(pm.ls(type="mesh")) > 0: for item in pm.ls(type="mesh"): parent_node = item.getParent() pm.delete(parent_node) # 清理捏脸骨骼动画 if pm.checkBox(self.face_make_node_check, q=True, value=True): faceMakeSets = [] extraSets = [] extraSets = ["L_eyeBall_socket", "L_eyeBall_socket_sdk", "R_eyeBall_socket", "R_eyeBall_socket_sdk", "headTipEnd_JNT", "facial_C_Nose_JNT", "facial_C_NoseBase_JNT", "head_JNT", "L_browMid_JNT", "L_browIn_JNT", "L_browOut_JNT", "L_brow_JNT", "R_browMid_JNT", "R_browIn_JNT", "R_browOut_JNT", "R_brow_JNT", ] pm.select("head_JNT", hi=True) for item in pm.ls(sl=True): if "definition_" in item.controller_name() and item.type() == "joint": faceMakeSets.append(item) for item in extraSets: if pm.objExists(item): faceMakeSets.append(item) pm.select(faceMakeSets) for jnt in pm.ls(sl=True): anim_attrs = pm.listAttr(jnt, k=True) for anim_attr in anim_attrs: cmd = '''cutKey -cl -t ":" -f ":" -at %s %s;''' % ( anim_attr, jnt.controller_name()) mel.eval(cmd) cmds.file(export_file_name, force=True, pr=True, ea=True, typ="FBX export", options="v=0") pm.textScrollList( self.output_scroll, e=True, a=export_file_name) pm.textScrollList( self.task_scroll, e=True, ri=export_file) return True
def delete_selected_mat(self): if self.list_materials.selectedItems(): selected_mat = self.list_materials.selectedItems()[0] material_node = pmc.PyNode(selected_mat.text()) pmc.delete(material_node) self.refresh_mat_list()
i = 0 refs = getTopLevelReferences() if not refs: LOG.debug("No References to import") return True LOG.debug("Importing {0} Top-Level Reference(s)".format(len(refs))) importReferences(refs, 1) # cleanup bad = getBadReferences() if len(bad): try: badlist = [str(b) for b in bad] pm.delete(bad) LOG.debug('Deleted bad references: {0}'.format(badlist)) except Exception as e: LOG.error('Could not delete bad references: {0}'.format(bad)) return True def importAllReferencesConfirm(): confirmKw = { 't':'Import All References', 'm':'This action is not undoable.\nContinue?', 'b':['OK', 'Cancel'], 'cb':'Cancel', 'ds':'dismiss', 'icn':'warning', }
def doRig(self): anchorList = [] cntrlList = [] locList = [] offCtrlLoc=[] offAuxLoc = [] dummyCrv = self.ribbonDict['moveallSetup']['nameTempl']+'_dummy_crv' pm.hide(pm.polyCube(n=dummyCrv)) if pm.objExists(self.ribbonDict['moveallSetup']['nameTempl']): pm.delete(self.ribbonDict['moveallSetup']['nameTempl']) if pm.objExists(self.ribbonDict['noMoveSetup']['nameTempl']): pm.delete(self.ribbonDict['noMoveSetup']['nameTempl']) ###Estrutura que nao deve ter transformacao noMoveSpace = pm.group(empty=True, n=self.ribbonDict['noMoveSetup']['nameTempl']) if not pm.objExists('NOMOVE'): pm.group(self.ribbonDict['noMoveSetup']['nameTempl'], n='NOMOVE') else: pm.parent(self.ribbonDict['noMoveSetup']['nameTempl'], 'NOMOVE') pm.parent(self.ribbonDict['moveallSetup']['nameTempl']+'_dummy_crv', noMoveSpace) noMoveSpace.visibility.set(0) noMoveSpace.translate.set(self.size * -0.5, 0, 0) noMoveBend1 = pm.nurbsPlane(p=(self.size * -0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) noMoveBend2 = pm.nurbsPlane(p=(self.size * 0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) noMoveCrvJnt = pm.curve(bezier=True, d=3, p=[(self.size * -0.50, 0, 0), (self.size * -0.499, 0, 0), (self.size * -0.496, 0, 0), (self.size * -0.495, 0, 0), (self.size * -0.395, 0, 0), (self.size * -0.10, 0, 0), (0, 0, 0), (self.size * 0.10, 0, 0), (self.size * 0.395, 0, 0), (self.size * 0.495, 0, 0), (self.size * 0.496, 0, 0), (self.size * 0.499, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 10, 10]) noMoveCrvTweak1 = pm.curve(d=2, p=[(self.size * -0.5, 0, 0), (self.size * -0.25, 0, 0), (self.size * 0, 0, 0)], k=[0, 0, 1, 1]) noMoveCrvTweak2 = pm.curve(d=2, p=[(self.size * 0.0, 0, 0), (self.size * 0.25, 0, 0), (self.size * 0.50, 0, 0)], k=[0, 0, 1, 1]) # Deformers das superficies noMove twist1 = pm.nonLinear(noMoveBend1[0], type='twist') # twist das superficies noMove twist2 = pm.nonLinear(noMoveBend2[0], type='twist') twist1[1].rotateZ.set(90) twist2[1].rotateZ.set(90) wireTweak1 = pm.wire(noMoveBend1[0], w=noMoveCrvTweak1, dds=[(0, 50)]) wireTweak2 = pm.wire(noMoveBend2[0], w=noMoveCrvTweak2, dds=[(0, 50)]) wireDef = pm.wire(noMoveBend1[0], noMoveBend2[0], w=noMoveCrvJnt, dds=[(0, 50)]) # Wire das superficies noMove wireDef[0].rotation.set(1) # seta wire controlando rotacao baseWire = [x for x in wireDef[0].connections() if 'BaseWire' in x.name()] baseWireTweak1 = [x for x in wireTweak1[0].connections() if 'BaseWire' in x.name()] baseWireTweak2 = [x for x in wireTweak2[0].connections() if 'BaseWire' in x.name()] pm.group(baseWire, baseWireTweak1, baseWireTweak2, noMoveCrvJnt, noMoveCrvTweak1, noMoveCrvTweak2, noMoveBend1[0], noMoveBend2[0], p=noMoveSpace, n=self.name + 'Deforms') pm.parent(twist1[1], twist2[1], noMoveSpace) ###Estrutura que pode ser movida cntrlsSpace = pm.group(empty=True, n=self.ribbonDict['moveallSetup']['nameTempl']) cntrlsSpace.translate.set(self.size * -0.5, 0, 0) bendSurf1 = pm.nurbsPlane(p=(self.size * -0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) bendSurf2 = pm.nurbsPlane(p=(self.size * 0.25, 0, 0), ax=(0, 0, 1), w=self.size * 0.5, lr=.1, d=3, u=5, v=1) # blendShape transferindo as deformaacoes para a superficie move blend1 = pm.blendShape(noMoveBend1[0], bendSurf1[0]) blend2 = pm.blendShape(noMoveBend2[0], bendSurf2[0]) pm.blendShape(blend1, e=True, w=[(0, 1)]) pm.blendShape(blend2, e=True, w=[(0, 1)]) pm.parent(bendSurf1[0], bendSurf2[0], cntrlsSpace) ##Cntrls tweak1Cls = pm.cluster(noMoveCrvTweak1.name()+'.cv[1]') tweak2Cls = pm.cluster(noMoveCrvTweak2.name() + '.cv[1]') displaySetup = self.ribbonDict['ctrlTweakSetup'].copy() cntrlName = displaySetup['nameTempl'] + '1' cntrlTweak1 = controlTools.cntrlCrv(name=cntrlName, obj=tweak1Cls[1], connType='connection', align='pivot', offsets=1, **displaySetup) cntrlName = displaySetup['nameTempl'] + '2' cntrlTweak2 = controlTools.cntrlCrv(name=cntrlName, obj=tweak2Cls[1], connType='connection', align='pivot', offsets=1, **displaySetup) controlTools.addMultiply([cntrlTweak1.getParent(), cntrlTweak2.getParent()]) tweakFoll1 = self.attachObj(obj=cntrlTweak1.getParent(3), mesh=bendSurf1[0], u=0.5, v=0.5, mode=4) tweakFoll2 = self.attachObj(obj=cntrlTweak2.getParent(3), mesh=bendSurf2[0], u=0.5, v=0.5, mode=4) tweakGrp = pm.group(tweak1Cls[1], tweak2Cls[1], n=self.name+'TweakCls_grp') pm.parent(tweakGrp, noMoveSpace) pm.parent(cntrlTweak1.getParent(3), cntrlTweak2.getParent(3), cntrlsSpace) for i in range(0, 7): anchor = pm.cluster(noMoveCrvJnt.name() + '.cv[' + str(i + 3) + ']') pm.cluster(anchor[1], e=True, g=dummyCrv) clsHandle = anchor[1] anchorGrp = pm.group(em=True, n=self.name+'clusterGrp' + str(i)) anchorDrn = pm.group(em=True, n=self.name+'clusterDrn' + str(i), p=anchorGrp) pos = pm.xform(anchor[1], q=True, ws=True, rp=True) pm.xform(anchorGrp, t=pos, ws=True) pm.parent(anchor[1], anchorDrn) anchorList.append(anchor[1]) if i == 0 or i == 6: displaySetup = self.ribbonDict['cntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) elif i == 3: displaySetup = self.ribbonDict['midCntrlSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) else: displaySetup = self.ribbonDict['cntrlTangSetup'].copy() cntrlName = displaySetup['nameTempl'] + str(i) cntrl = controlTools.cntrlCrv(name=cntrlName, obj=anchor[1], **displaySetup) offCtrlLoc.append(pm.spaceLocator(n=cntrlName+'off_loc')) offCtrlLoc[-1].localScale.set(0.2, 0.2, 0.2) pm.parent(offCtrlLoc[-1], cntrl, r=True) if i in [1, 2, 4, 5]: offCtrlLoc[-1].getShape().visibility.set(False) # Nao pode fazer conexao na criacao do controle, pois tera conexao direta pm.xform(cntrl.getParent(), t=pos, ws=True) # estrutura de buffers para conexao direta auxLocGrp = pm.group(em=True, n=self.name + 'Aux_grp') auxLoc = pm.group(em=True, p=auxLocGrp, n=self.name + str(i)+ 'Aux_loc') pm.xform(auxLocGrp, t=pos, ws=True) loc = pm.PyNode(auxLoc) if i==0 or i==3 or i==6: tmpOffAuxLoc = pm.group(em=True, n=self.name + str(i) + 'AuxOff_loc') offAuxLoc.append(tmpOffAuxLoc) pm.parent(tmpOffAuxLoc, auxLoc, r=True) offCtrlLoc[-1].translate >> offAuxLoc[-1].translate offCtrlLoc[-1].rotate >> offAuxLoc[-1].rotate if i == 1 or i == 4: pm.xform(anchorGrp, s=(-1, 1, 1), r=True) pm.xform(cntrl.getParent(), s=(-1, 1, 1), r=True) pm.xform(loc.getParent(), s=(-1, 1, 1), r=True) # Conexoes dos buffers cm os clusters e com os controles pm.parentConstraint(cntrl, loc, mo=True) loc.translate >> anchorDrn.translate loc.rotate >> anchorDrn.rotate cntrlList.append(cntrl) locList.append(loc) # workaround do flip do inicio do wire(adicao de mais pontos) startCls = pm.cluster(noMoveCrvJnt.name() + '.cv[0:2]') endCls = pm.cluster(noMoveCrvJnt.name() + '.cv[10:14]') pm.cluster(startCls[1], e=True, g=dummyCrv) pm.cluster(endCls[1], e=True, g=dummyCrv) pm.parent(startCls[1], anchorList[0]) pm.parent(endCls[1], anchorList[6]) cntrlsSpace.addAttr('midCtrlViz', at='double', dv=1, max=1, min=0, k=True, h=False) cntrlsSpace.addAttr('bezierCtrlViz', at='double', dv=1,max=1, min=0, k=True, h=False) cntrlsSpace.addAttr('bendExtraCtrlViz', at='double',max=1, min=0, dv=1, k=True, h=False) cntrlsSpace.addAttr('extraCtrlsVis', at='double', dv=0,max=1, min=0, k=True, h=False) cntrlList[0].addAttr('twist', at='double', dv=0, k=True) cntrlList[0].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[0].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[3].addAttr('twist', at='double', dv=0, k=True) cntrlList[3].addAttr('autoVolume', at='double', dv=0, k=True) cntrlList[6].addAttr('twist', at='double', dv=0, k=True) cntrlList[6].addAttr('stretchDist', at='double', dv=0, k=True) cntrlList[6].addAttr('autoVolumStregth', at='double', dv=0, k=True) cntrlList[0].twist >> twist1[0].endAngle cntrlList[3].twist >> twist1[0].startAngle cntrlList[3].twist >> twist2[0].endAngle cntrlList[6].twist >> twist2[0].startAngle # cria sistema do tweak pra compensar twist da ribbon tweak1Twist1Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak1Twist2Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak1Add = pm.createNode('addDoubleLinear', name='tweak1Add') tweak2Twist1Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak2Twist2Multi = pm.createNode('multDoubleLinear', name='tweak1Twist1Multi') tweak2Add = pm.createNode('addDoubleLinear', name='tweak1Add') cntrlList[0].twist >> tweak1Twist1Multi.input1 tweak1Twist1Multi.input2.set(-0.5) cntrlList[3].twist >> tweak1Twist2Multi.input1 tweak1Twist2Multi.input2.set (-0.5) tweak1Twist1Multi.output >> tweak1Add.input1 tweak1Twist2Multi.output >> tweak1Add.input2 tweak1Add.output >> cntrlTweak1.getParent(2).rotate.rotateX cntrlList[6].twist >> tweak2Twist1Multi.input1 tweak2Twist1Multi.input2.set(-0.5) cntrlList[3].twist >> tweak2Twist2Multi.input1 tweak2Twist2Multi.input2.set(-0.5) tweak2Twist1Multi.output >> tweak2Add.input1 tweak2Twist2Multi.output >> tweak2Add.input2 tweak2Add.output >> cntrlTweak2.getParent(2).rotate.rotateX # hierarquia pm.parent(anchorList[1].getParent(2), anchorList[0]) pm.parent(anchorList[5].getParent(2), anchorList[6]) pm.parent(anchorList[2].getParent(2), anchorList[4].getParent(2), anchorList[3]) pm.parent(cntrlList[1].getParent(), offCtrlLoc[0]) pm.parent(cntrlList[5].getParent(), offCtrlLoc[6]) pm.parent(cntrlList[2].getParent(), cntrlList[4].getParent(), offCtrlLoc[3]) pm.parent(cntrlList[3].getParent(), cntrlList[0].getParent(), cntrlList[6].getParent(), cntrlsSpace) pm.parent(locList[1].getParent(), offAuxLoc[0]) pm.parent(locList[5].getParent(), offAuxLoc[2]) pm.parent(locList[2].getParent(), locList[4].getParent(), offAuxLoc[1]) pm.parent(locList[3].getParent(), locList[0].getParent(), locList[6].getParent(), cntrlsSpace) pm.parent(anchorList[3].getParent(2), anchorList[0].getParent(2), anchorList[6].getParent(2), noMoveSpace) for i, j in zip([1, 2, 4, 5], [0, 3, 3, 6]): crv = pm.curve(d=1, p=[(1, 0, 0), (-1, 0, 0)], k=[0, 1]) crv.inheritsTransform.set(False) crv.template.set(True) offCtrlLoc[i].worldPosition[0] >> crv.getShape().controlPoints[0] offCtrlLoc[j].worldPosition[0] >> crv.getShape().controlPoints[1] pm.parent(crv, offCtrlLoc[i], r=True) # Skin joints do ribbon skinJntsGrp = pm.group(em=True, n=self.name + 'SkinJnts') follGrp = pm.group(em=True, n=self.name + 'Foll_grp') pm.parent(tweakFoll1, tweakFoll2, follGrp) # cria ramps para controlar o perfil de squash e stretch ramp1 = pm.createNode('ramp', n=self.name+'SquashRamp1') ramp1.attr('type').set(1) ramp2 = pm.createNode('ramp', n=self.name+'SquashRamp2') ramp2.attr('type').set(1) expre1 = "float $dummy = " + ramp1.name() + ".outAlpha;float $output[];float $color[];" expre2 = "float $dummy = " + ramp2.name() + ".outAlpha;float $output[];float $color[];" extraCntrlsGrp = pm.group(em=True, r=True, p=cntrlsSpace, n=self.name + 'ExtraCntrls') # loop pra fazer os colocar o numero escolhido de joints ao longo do ribbon. # cria tmb node tree pro squash/stretch # e controles extras vIncrement = float((1.0 - (self.offsetStart + self.offsetEnd)) / ((self.numJnts - 2) / 2.0)) for i in range(1, (self.numJnts / 2) + 1): # cria estrutura pra superficie 1 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + 'A' + str(i) + self.jntSulfix jnt1 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt1) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'A' + str(i) cntrl1 = controlTools.cntrlCrv(name=cntrlName, obj=jnt1, connType='constraint', **displaySetup) # node tree blend1A = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend1A') blend1B = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend1B') gammaCorr1 = pm.createNode('gammaCorrect', n=self.name+'VolumeGamma1') cntrlList[0].attr('autoVolumStregth') >> gammaCorr1.gammaX cntrlList[0].attr('stretchDist') >> gammaCorr1.value.valueX blend1A.input[0].set(1) gammaCorr1.outValueX >> blend1A.input[1] blend1B.input[0].set(1) blend1A.output >> blend1B.input[1] cntrlList[3].attr ('autoVolume') >> blend1B.attributesBlender blend1B.output >> cntrl1.getParent().scaleY blend1B.output >> cntrl1.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre1 = expre1 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp1.name() + " `;$output[" + str( i) + "] = $color[0];" + blend1A.name() + ".attributesBlender=$output[" + str(i) + "];" # cria estrutura pra superficie 2 pm.select(cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] + 'B' + str(i) + self.jntSulfix jnt2 = pm.joint(p=(0, 0, 0), n=jntName) self.skinJoints.append(jnt2) displaySetup = self.ribbonDict['cntrlExtraSetup'].copy() cntrlName = displaySetup['nameTempl'] + 'B' + str(i) cntrl2 = controlTools.cntrlCrv(name=cntrlName, connType='constraint', obj=jnt2, **displaySetup) # node tree blend2A = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend2A') blend2B = pm.createNode('blendTwoAttr', n=self.name+'VolumeBlend2B') gammaCorr2 = pm.createNode('gammaCorrect', n=self.name+'VolumeGamma2') cntrlList[6].attr('autoVolumStregth') >> gammaCorr2.gammaX cntrlList[6].attr('stretchDist') >> gammaCorr2.value.valueX blend2A.input[0].set(1) gammaCorr2.outValueX >> blend2A.input[1] blend2B.input[0].set(1) blend2A.output >> blend2B.input[1] cntrlList[3].attr('autoVolume') >> blend2B.attributesBlender blend2B.output >> cntrl2.getParent().scaleY blend2B.output >> cntrl2.getParent().scaleZ # expressao que le a rampa para setar valores da escala de cada joint quando fizer squash/stretch expre2 = expre2 + "$color = `colorAtPoint -o RGB -u " + str( self.offsetStart + (i - 1) * vIncrement) + " -v 0.5 " + ramp2.name() + " `;$output[" + str( i) + "] = $color[0];" + blend2A.name() + ".attributesBlender=$output[" + str(i) + "];" # prende joints nas supeficies com follicules foll1 = self.attachObj(cntrl1.getParent(), bendSurf1[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) foll2 = self.attachObj(cntrl2.getParent(), bendSurf2[0], self.offsetStart + (i - 1) * vIncrement, 0.5, 4) pm.parent(cntrl1.getParent(), cntrl2.getParent(), extraCntrlsGrp) pm.parent(jnt1, jnt2, skinJntsGrp) pm.parent(foll1, foll2, follGrp) pm.select (cl=True) jntName = self.ribbonDict['jntSetup']['nameTempl'] +'Elbow' + self.jntSulfix elbowJnt = pm.joint(p=(0, 0, 0), n=jntName) pm.parent(elbowJnt, skinJntsGrp) elbowAuxFoll1 = self.createFoll(bendSurf1[0], 0.999, 0.5) elbowAuxFoll2 = self.createFoll(bendSurf2[0], 0.001, 0.5) pm.parent(elbowAuxFoll1, elbowAuxFoll2, follGrp) orientConstraint = pm.PyNode(pm.orientConstraint(elbowAuxFoll1, elbowAuxFoll2, elbowJnt, mo=False)) orientConstraint.interpType.set(2) pm.pointConstraint(cntrlList[3], elbowJnt, mo=False) # seta expressoes para so serem avaliadas por demanda pm.expression(s=expre1, ae=False, n=self.name+'Expression1') pm.expression(s=expre2, ae=False, n=self.name+'Expression2') pm.parent(skinJntsGrp, cntrlsSpace) pm.parent(follGrp, noMoveSpace) # hideCntrls pm.toggle(bendSurf1[0], bendSurf2[0], g=True) bendSurf1[0].visibility.set(0) bendSurf2[0].visibility.set (0) # skinJntsGrp.visibility.set(0) cntrlsSpace.extraCtrlsVis >> extraCntrlsGrp.visibility cntrlsSpace.bezierCtrlViz >> cntrlList[0].getParent().visibility cntrlsSpace.midCtrlViz >> cntrlList[3].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[4].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[2].getParent().visibility cntrlsSpace.bezierCtrlViz >> cntrlList[6].getParent().visibility cntrlsSpace.bendExtraCtrlViz >> cntrlTweak1.getParent().visibility cntrlsSpace.bendExtraCtrlViz >> cntrlTweak2.getParent().visibility # povoa ribbon Dict self.ribbonDict['name'] = 'bezierRibbon' self.ribbonDict['ribbonMoveAll'] = cntrlsSpace for i in range(0, 7): self.ribbonDict['cntrl' + str(i)] = cntrlList[i]
def custom_bake(self, time_range): stepped_limit = 0.0001 # get objects to bake # baked_objects = list(self.original_selection) # copy the list # joints = pm.listRelatives(self.original_selection, allDescendents=True, type='joint') # baked_objects.extend(pm.listRelatives(self.original_selection, allDescendents=True, type='transform')) # pm.select(baked_objects, r=True) # obj_list = om.MGlobal.getActiveSelectionList() # iterator = om.MItSelectionList(obj_list, om.MFn.kDagNode) try: to_bake = pm.ls(self.original_selection, type='transform') to_bake += pm.listRelatives(self.original_selection, allDescendents=True, type='transform') # create a set, and add all joints to the set filtered = set(pm.ls(self.original_selection, type='joint')) filtered |= set(pm.listRelatives(self.original_selection, allDescendents=True, type='joint')) # union op. except Exception as e: sys.stdout.write("error 1: %s\n" % e) # add blendshapes and animated transforms to the set blendshapes = set() for node in to_bake: # blendshape? try: for shape in node.getShapes(): shape_inputs = shape.inputs() # shape_inputs.extend(shape.attr('inMesh').inputs()) # maybe not needed # this should perhaps be rewritten as a recursive function, # that keeps traversing down the hierarchy for shape_input in shape_inputs: if pm.nodeType(shape_input) == 'blendShape': blendshapes.add(shape_input) elif pm.nodeType(shape_input) in ('skinCluster', 'objectSet'): for inp in shape_input.inputs(): if pm.nodeType(inp) == 'blendShape': blendshapes.add(inp) except Exception as e: pm.warning("Could not determine blendshape: %s" % e) # any inputs to transform attributes? i.e. any animation? for at in self.transform_attributes: if pm.hasAttr(node, at) and len(node.attr(at).inputs()) > 0: filtered.add(node) break to_bake = list(filtered.union(blendshapes)) samples = 1 has_stepped = self.has_stepped_checkbox.isChecked() if has_stepped: samples = 0.5 maya.utils.processIdleEvents() qApp.processEvents() if len(to_bake) == 0: pm.select(self.original_selection, r=True) return # set key tangent to auto when baking itt = pm.keyTangent(q=True, g=True, itt=True) ott = pm.keyTangent(q=True, g=True, ott=True) pm.keyTangent(g=True, itt='auto', ott='auto') # bake selected transforms and children with half step pm.bakeResults(to_bake, time=time_range, sampleBy=samples, hierarchy='none', disableImplicitControl=True, preserveOutsideKeys=False, sparseAnimCurveBake=False, simulation=True, minimizeRotation=False, removeBakedAnimFromLayer=True) # set key tangent back to default pm.keyTangent(g=True, itt=itt, ott=ott) pm.flushUndo() # maya.utils.processIdleEvents() # qApp.processEvents() # remove static channels to speed up analysis # to_bake.extend(joints) try: pm.select(to_bake, r=True) pm.delete(staticChannels=True) except Exception as e: sys.stdout.write(str(e) + '\n') muted_curves = [] # progress bar try: gMainProgressBar = maya.mel.eval('$tmp = $gMainProgressBar') pm.progressBar(gMainProgressBar, e=True, beginProgress=True, isInterruptable=True, status='Working...', maxValue=len(to_bake)) except Exception as e: sys.stdout.write(str(e) + '\n') for obj in to_bake: for curve in pm.keyframe(obj, q=True, name=True): # find muted curves connection = pm.listConnections(curve, d=True, s=False)[0] if pm.nodeType(connection) == 'mute': if pm.getAttr('%s.mute' % connection): muted_curves.append(curve) continue # analyse half frames to determine which are stepped if has_stepped: for key in range(int(time_range[0]), int(time_range[1])): try: epsilon_half = abs(pm.keyframe(curve, q=True, valueChange=True, time=(key,))[0] - pm.keyframe(curve, q=True, valueChange=True, time=(key + 0.5,))[0]) epsilon_full = abs(pm.keyframe(curve, q=True, valueChange=True, time=(key,))[0] - pm.keyframe(curve, q=True, valueChange=True, time=(key + 1))[0]) if epsilon_half < stepped_limit < epsilon_full: pm.keyTangent(curve, time=(key,), ott='step') except IndexError: continue # update progress pm.progressBar(gMainProgressBar, e=True, step=1) if pm.progressBar(gMainProgressBar, q=True, isCancelled=True): break # end progressbar pm.progressBar(gMainProgressBar, e=True, endProgress=True) qApp.processEvents() pm.delete(muted_curves) # remove unsnapped keys if has_stepped: pm.selectKey(to_bake, unsnappedKeys=True) pm.cutKey(animation='keys', clear=True) # apply euler filter if self.euler_filter_checkbox.isChecked(): self.apply_euler_filter(to_bake) pm.currentTime(time_range[0]) # set a key on the first frame # todo: when doing stepped animation, all rotations needs to be either stepped or not, because of the way unity interpolates try: if has_stepped: tangent_type = 'step' else: tangent_type = 'auto' if to_bake: pm.setKeyframe(to_bake, attribute=self.transform_attributes, t=time_range[0], insertBlend=False, ott=tangent_type) if blendshapes: pm.setKeyframe(blendshapes, t=time_range[0], insertBlend=False, ott=tangent_type) except Exception as e: sys.stdout.write(str(e) + '\n') # re-select original selection, so that we export the right thing pm.select(self.original_selection, r=True) # select all child constraints if enabled if self.constraints_checkbox.isChecked(): constraints = pm.listRelatives(pm.ls(sl=True), allDescendents=True, type='constraint') pm.select(constraints, add=True)
def tearDown(self): pm.delete(self.pcs) pm.delete(self.pcs2) pm.delete(self.pct)
def createEdgeJoints(edges): joints = [] # Do this for every edge for edge in edges: # Get the vertices the edge is connected to edgeVerts = edge.connectedVertices() # Cluster the verts. #We will use this to get the position for our joint clusTfm = pm.cluster(edgeVerts)[1] pm.select(clear=True) # Create our joint jnt = pm.joint() # getPosition doesn't give us the correct result. This does pos = clusTfm.rotatePivot.get() # We don't need the cluster any more pm.delete(clusTfm) # Now we calculate the average normal normals = [] for face in edge.connectedFaces(): # Collect the normal of every face normals.append(face.getNormal(space="world")) # Variable that will store the sum of all normals normalsSum = pm.datatypes.Vector() for normal in normals: normalsSum += normal # This will be our vector for the x axis # Average normal. #We divide the normal by the total number of vectors xVec = (normalsSum / len(normals)) # The vertex that has the highest position, #will be the vertex that our Y axis will point to for i, vert in enumerate(edgeVerts): # We take the first vert as our up vector if i == 0: upVec = edgeVerts[0].getPosition(space="world") # And compare the other to it vertPos = edgeVerts[i].getPosition(space="world") if vertPos[1] >= upVec[1]: upVec = vertPos # This gives us a vector that points from the center #of the selection to the highest vertex upVec = upVec - pos # We get the z vector from the cross product of our x vector #and the up vector zVec = xVec.cross(upVec) # Calculate the y vec the same way. We could use the upVec #but this way we make sure they are all correct yVec = zVec.cross(xVec) # Normalize all vectors so scaling doesn't get messed up xVec.normalize() yVec.normalize() zVec.normalize() # Construct the matrix from the vectors we calculated jntMtx = pm.dt.Matrix(xVec, yVec, zVec, pos) # And set the joints matrix to our new matrix jnt.setMatrix(jntMtx) # This transfers the rotation values #to the joint orientation values. pm.makeIdentity(jnt, r=True, apply=True) joints.append(jnt) return joints
def from_seq(self, seq): """Generates maya shots and sequencers with the given :class:`anima.previs.Sequence` instance. This method is designed to mainly be used with :method:`.from_xml` and :method:`.from_edl` methods. It generates new shots or updates them by looking at the given :class:`anima.previs.Sequence` instance. :param seq: An :class:`anima.previs.Sequence` instance :return: """ # now create or update structure # create first # generate the shot name template first shot_name_template = self.get_shot_name_template() # get current sequencer seqs = self.sequences.get() if seqs: # we probably need to update shots seq1 = seqs[0] # update shots shots = seq1.shots.get() # collect clips all_clips = [ clip for track in seq.media.video.tracks for clip in track.clips ] deleted_shots = [] used_shots = [] # for each shot sets the anchor point in a temp variable for shot in shots: shot.anchor = shot.startFrame.get() # find the corresponding shots in seq for clip in all_clips: #is_deleted = True for shot in shots: if clip.id.lower() == shot.full_shot_name.lower(): # update with the given clip info # anchor = shot.startFrame.get() handle = shot.handle.get() track = shot.track.get() if shot in used_shots: # this shot has been used once so duplicate it # before doing anything dup_shot = seq1.create_shot(shot.shotName.get()) dup_shot.startFrame.set(shot.startFrame.get()) dup_shot.endFrame.set(shot.endFrame.get()) dup_shot.handle.set(shot.handle.get()) dup_shot.sequenceStartFrame.set( shot.sequenceStartFrame.get()) # do not copy sequenceEndFrame # copy camera dup_shot.set_camera(shot.get_camera()) dup_shot.anchor = shot.anchor shot = dup_shot start_frame = clip.in_ - handle + shot.anchor end_frame = clip.out - clip.in_ + start_frame - 1 # print '-------------------------------' # print 'clip.in : %s' % clip.in_ # print 'clip.out : %s' % clip.out # print 'clip.start : %s' % clip.start # print 'clip.end : %s' % clip.end # print 'start_frame : %s' % start_frame # print 'end_frame : %s' % end_frame sequence_start = clip.start shot.startFrame.set(start_frame) shot.endFrame.set(end_frame) shot.sequenceStartFrame.set(sequence_start) # set original track shot.track.set(track) used_shots.append(shot) break for shot in seq1.shots.get(): if shot not in used_shots: deleted_shots.append(shot) # delete shots pm.delete(deleted_shots) else: # create sequencer seq1 = self.create_sequence(seq.name) # create shots media = seq.media for i, track in enumerate(media.video.tracks): for clip in track.clips: # clip.id is something like SEQ001_HSNI_010_0010_v046 # filter the shot name shot_name = clip.id.split('_')[-2] shot = seq1.create_shot(shot_name) shot.startFrame.set(clip.in_) shot.endFrame.set(clip.out - 1) shot.sequenceStartFrame.set(clip.start) shot.handle.set(0) if clip.file: f = clip.file pathurl = f.pathurl.replace('file://localhost/', '') if ':' not in pathurl: # not windows, keep '/' pathurl = '/%s' % pathurl shot.output.set(pathurl) shot.track.set(i + 1)
def run(self): if not pm.selected(): return for source_node in pm.selected()[:]: target_node = None # -- Look for the object in the alternate side try: if crab.config.LEFT in source_node.name(): target_node = pm.PyNode( source_node.name().replace( crab.config.LEFT, crab.config.RIGHT, ) ) else: target_node = pm.PyNode( source_node.name().replace( crab.config.RIGHT, crab.config.LEFT, ) ) except: print('%s does not have an alternate side' % source_node) # -- Read the shape data from the current side shape_data = crab.utils.shapes.read(source_node) # -- Clear the shapes on the other side if target_node.getShapes(): pm.delete(target_node.getShapes()) # -- Apply the shapes to that side crab.utils.shapes.apply(target_node, shape_data) # -- Invert the shape globally for source_shape, target_shape in zip(source_node.getShapes(), target_node.getShapes()): for idx in range(source_shape.numCVs()): # -- Get the worldspace position of the current cv source_pos = source_shape.getCV( idx, space='world', ) # -- Set the position of the cv with the X axis # -- inverted target_shape.setCV( idx, [ source_pos[0], source_pos[1], source_pos[2] * -1, ], space='world', ) # -- Update teh curve to propagate the change target_shape.updateCurve()
def load(self, context, name, namespace, data): import pymel.core as pm new_nodes = [] image_plane_depth = 1000 asset = context['asset']['name'] namespace = namespace or lib.unique_namespace( asset + "_", prefix="_" if asset[0].isdigit() else "", suffix="_", ) # Get camera from user selection. camera = None default_cameras = ["frontShape", "perspShape", "sideShape", "topShape"] cameras = [ x for x in pm.ls(type="camera") if x.name() not in default_cameras ] camera_names = {x.getParent().name(): x for x in cameras} camera_names["Create new camera."] = "create_camera" window = CameraWindow(camera_names.keys()) window.exec_() camera = camera_names[window.camera] if camera == "create_camera": camera = pm.createNode("camera") if camera is None: return try: camera.displayResolution.set(1) camera.farClipPlane.set(image_plane_depth * 10) except RuntimeError: pass # Create image plane image_plane_transform, image_plane_shape = pm.imagePlane( camera=camera, showInAllViews=False) image_plane_shape.depth.set(image_plane_depth) image_plane_shape.imageName.set( context["representation"]["data"]["path"]) start_frame = pm.playbackOptions(q=True, min=True) end_frame = pm.playbackOptions(q=True, max=True) image_plane_shape.frameOffset.set(1 - start_frame) image_plane_shape.frameIn.set(start_frame) image_plane_shape.frameOut.set(end_frame) image_plane_shape.frameCache.set(end_frame) image_plane_shape.useFrameExtension.set(1) movie_representations = ["mov", "preview"] if context["representation"]["name"] in movie_representations: # Need to get "type" by string, because its a method as well. pm.Attribute(image_plane_shape + ".type").set(2) # Ask user whether to use sequence or still image. if context["representation"]["name"] == "exr": # Ensure OpenEXRLoader plugin is loaded. pm.loadPlugin("OpenEXRLoader.mll", quiet=True) message = ("Hold image sequence on first frame?" "\n{} files available.".format( len(context["representation"]["files"]))) reply = QtWidgets.QMessageBox.information( None, "Frame Hold.", message, QtWidgets.QMessageBox.Ok, QtWidgets.QMessageBox.Cancel) if reply == QtWidgets.QMessageBox.Ok: pm.delete( image_plane_shape.listConnections(type="expression")[0]) image_plane_shape.frameExtension.set(start_frame) new_nodes.extend([ image_plane_transform.longName().split("|")[-1], image_plane_shape.longName().split("|")[-1] ]) for node in new_nodes: pm.rename(node, "{}:{}".format(namespace, node)) return containerise(name=name, namespace=namespace, nodes=new_nodes, context=context, loader=self.__class__.__name__)
def aim_constraint_( source=None, target=None, maintain_offset=True, axes=["X", "Y", "Z"], aim_axes=[1, 0, 0], up_axes=[0, 1, 0], world_up_type="object", kill_up_vec_obj=None, parent_up_vec_obj=None, world_up_object=None, world_up_vector=[0, 1, 0], ): """ Create a aimConstraint. By default it creates a object as upVector. Args: source(dagnode): The source node. target(dagnode): The target node. maintain_offset(bool): If the constraint should keep the offset of the target. axes(list): The axes to contraint as strings. aim_axes(list): The axes to aim for. ['x','y','z'] = [1,1,1] up_axes(list): The axes to the up vector. ['x','y','z'] = [1,1,1] world_up_type(string): The type for the up vector. Valid: none, scene, vector, object, objectrotation. kill_up_vec_obj(bool): Kills the up vector transform. parent_up_vec_obj(dagnode): The parent for the up vector. world_up_object(dagnode): The up vector transform node. world_up_vector(list): The axes for the world up vector. ['x','y','z'] = [1,1,1] Return: list: The aim constraint, the upVector locator node. """ skip_axes = ["x", "y", "z"] temp = [] if world_up_type == "object": if not world_up_object: world_up_object = pmc.spaceLocator(n=str(source) + "_upVec_0_LOC") world_up_object_buffer = pmc.group( world_up_object, n=str(world_up_object) + "_buffer_GRP" ) temp.append(world_up_object_buffer) pmc.delete( pmc.parentConstraint(source, world_up_object_buffer, mo=False) ) world_up_object.translate.set(v * 5 for v in up_axes) con = pmc.aimConstraint( target, source, mo=maintain_offset, aim=aim_axes, skip=skip_axes, u=up_axes, worldUpType=world_up_type, worldUpObject=world_up_object, ) elif world_up_type == "objectrotation": con = pmc.aimConstraint( target, source, mo=maintain_offset, aim=aim_axes, skip=skip_axes, u=up_axes, worldUpType=world_up_type, worldUpObject=world_up_object, ) elif world_up_type == "vector": con = pmc.aimConstraint( target, source, mo=maintain_offset, aim=aim_axes, skip=skip_axes, u=up_axes, worldUpType=world_up_type, worldUpVector=world_up_vector, ) else: con = pmc.aimConstraint( target, source, mo=maintain_offset, aim=aim_axes, skip=skip_axes, u=up_axes, worldUpType=world_up_type, ) for ax in axes: con.attr("constraintRotate" + ax.upper()).connect( source.attr("rotate" + ax.upper()) ) temp.append(world_up_object) if kill_up_vec_obj: pmc.delete(temp) return [con] if parent_up_vec_obj: pmc.parent(temp[0], parent_up_vec_obj) return [con, temp[:]]
def PlaceOnComponent(): # Variables to store selected edges, #verts and faces those edges are connected to verts = [] edges = [] faces = [] shp = '' # Get the selection and flatten it. #Otherwise Maya might return lists and not individual elements sel = pm.selected(flatten=True) # Get the selected edges for s in sel: # Get the selections type objType = s.__class__.__name__ shp = pm.PyNode(s.split('.')[0]) # If the type is MeshEdge then append the edge to our list if objType == "MeshEdge": edges.append(s) if objType == "MeshFace": faces.append(s) if objType == "MeshVertex": verts.append(s) if verts: for vert in verts: jnts = createEdgeJoints(vert.connectedEdges()) pm.select(clear=True) jnt = pm.joint() pm.xform(jnt, worldSpace=True, translation=vert.getPosition(space='world')) pm.delete( pm.orientConstraint(jnts[0], jnts[1], jnts[2], jnts[3], jnt)) pm.delete(jnts) pm.makeIdentity(jnt, r=True, apply=True) if faces: for face in faces: faceVerts = face.getVertices() faceVertsPos = [ shp.vtx[faceVerts[0]].getPosition(space='world'), shp.vtx[faceVerts[1]].getPosition(space='world'), shp.vtx[faceVerts[2]].getPosition(space='world'), shp.vtx[faceVerts[3]].getPosition(space='world') ] avg = [float(sum(col)) / len(col) for col in zip(*faceVertsPos)] ySorted = sorted(faceVertsPos, key=itemgetter(1)) highestVerts = [ shp.vtx[faceVerts[faceVertsPos.index(ySorted[2])]], shp.vtx[faceVerts[faceVertsPos.index(ySorted[3])]] ] clusTfm = pm.cluster(highestVerts)[1] upLoc = pm.spaceLocator() pm.pointConstraint(clusTfm, upLoc) faceEdges = face.getEdges() faceEdges = [ shp.e[faceEdges[0]], shp.e[faceEdges[1]], shp.e[faceEdges[2]], shp.e[faceEdges[3]] ] jnts = createEdgeJoints(faceEdges) pm.select(clear=True) jnt = pm.joint() pm.xform(jnt, worldSpace=True, translation=avg) pm.delete( pm.orientConstraint(jnts[0], jnts[1], jnts[2], jnts[3], jnt)) pm.delete(jnts) pm.select(clear=True) aimLoc = pm.spaceLocator() pm.xform(aimLoc, worldSpace=True, translation=avg) pm.delete(pm.orientConstraint(jnt, aimLoc)) pm.parent(aimLoc, jnt) aimLoc.tx.set(1) pm.parent(aimLoc, w=True) pm.delete( pm.aimConstraint(aimLoc, jnt, worldUpType='object', worldUpObject=upLoc)) pm.delete(upLoc, aimLoc, clusTfm) pm.makeIdentity(jnt, r=True, apply=True) # Continue only if we have edges selected if edges: createEdgeJoints(edges)
def delete_rigid_body_to_joint_constraint(self): ''' # deletes the rigid body object's constraint ''' pm.delete(self.parent_constraint)
def finalize(self): """Finalize the rig.""" groupIdx = 0 # Properties -------------------------------------- mgear.log("Finalize") # clean jnt_org -------------------------------------- mgear.log("Cleaning jnt org") for jOrg in dag.findChildrenPartial(self.jnt_org, "org"): if not jOrg.listRelatives(c=True): pm.delete(jOrg) # Groups ------------------------------------------ mgear.log("Creating groups") # Retrieve group content from components for name in self.componentsIndex: component_ = self.components[name] for name, objects in component_.groups.items(): self.addToGroup(objects, name) for name, objects in component_.subGroups.items(): self.addToSubGroup(objects, name) # Create master set to group all the groups masterSet = pm.sets(n=self.model.name() + "_sets_grp", em=True) pm.connectAttr(masterSet.message, self.model.rigGroups[groupIdx]) groupIdx += 1 # Creating all groups pm.select(cl=True) for name, objects in self.groups.items(): s = pm.sets(n=self.model.name() + "_" + name + "_grp") s.union(objects) pm.connectAttr(s.message, self.model.rigGroups[groupIdx]) groupIdx += 1 masterSet.add(s) for parentGroup, subgroups in self.subGroups.items(): pg = pm.PyNode(self.model.name() + "_" + parentGroup + "_grp") for sg in subgroups: sub = pm.PyNode(self.model.name() + "_" + sg + "_grp") if sub in masterSet.members(): masterSet.remove(sub) pg.add(sub) # Bind pose --------------------------------------- # controls_grp = self.groups["controllers"] # pprint(controls_grp, stream=None, indent=1, width=100) pm.select(self.groups["controllers"]) node = pm.dagPose(save=True, selection=True) pm.connectAttr(node.message, self.model.rigPoses[0]) print node # Bind skin re-apply if self.options["importSkin"]: try: pm.displayInfo("Importing Skin") skin.importSkin(self.options["skin"]) except RuntimeError: pm.displayWarning("Skin doesn't exist or is not correct. " + self.options["skin"] + " Skipped!")
def copyLocRot(xform, loc_node, rot_node): xform, loc_node, rot_node = (pm.ls(arg)[0] for arg in (xform, loc_node, rot_node)) pm.delete(pm.pointConstraint(loc_node, xform)) pm.delete(pm.orientConstraint(rot_node, xform))
def connectTextures(self, material, warn=True): """ Connects the textures in self.texture_paths to the given material. Will attempt to use relative paths. Args: material (pm.nodetypes.ShaderfxShader): Norrsken PBR shaderFX material used to connect textures to. warn (boolean): If True, will warn user if no textures found. """ if material.type() != 'ShaderfxShader': pm.error(material.nodeName() + ' is not a ShaderfxShader!') if not self.texture_paths: self.getTextures(warn=warn) # odd check to make sure we dont over warn user if textures are not found by getting textures if not self.texture_paths and self.texture_paths is not None: return pm.warning('No textures found in ' + self.textures_directory) if warn else None art_directory = store.get(pcfg.art_directory) material_name = material.nodeName().lstrip(pcfg.material_prefix) for texture_path in self.texture_paths: texture_name, _ = os.path.splitext(os.path.basename(texture_path)) if not (material_name in texture_name): continue # use relative texture path if possible texture_path = texture_path.lstrip(art_directory + '/') # diffuse/base color if texture_name.endswith(pcfg.diffuse_suffix): material.Use_Base_Color.set(True) material.Base_Color.set(texture_path) # file nodes have a nice attribute that tests whether a file has alpha or not opacity_tester = pm.createNode('file', name='opacityTest') opacity_tester.fileTextureName.set(texture_path) # set opacity blending mode to blending instead of clipping if file has alpha if opacity_tester.fileHasAlpha.get(): pm.mel.eval( 'shaderfx -sfxnode "{}" -edit_bool 1291 "value" false;' .format(material.nodeName())) pm.delete(opacity_tester) # packed ambient occlusion, roughness, and metallic elif texture_name.endswith(pcfg.ao_r_m_suffix): material.Use_Occlusion_Roughness_Metallic.set(True) material.Occ_Rgh_Mtl.set(texture_path) # normal elif texture_name.endswith(pcfg.normal_suffix): material.Use_Normal.set(True) material.Normal.set(texture_path) # emissive/glow elif texture_name.endswith(pcfg.emissive_suffix): material.Use_Emissive.set(True) material.Emissive.set(texture_path) elif warn: pm.warning(texture_path + ' does not have a valid suffix!') # display textures in the main model viewport pane pm.modelEditor('modelPanel4', e=True, tx=True, dtx=True)
def Ik_To_Fk_Switch_Button(): selection = pm.ls(sl=True) namespace_correct = selection[0].split(':')[:-1] if len(selection)>0: side = selection[0].split('_')[1] shoulderSwitchCtrl = namespace_correct[0]+':'+'FK_shoulder_switch_'+side+'_Ctrl' ElbowSwitchCtrl = namespace_correct[0]+':'+'FK_Elbow_switch_'+side+'_Ctrl' wristSwitchCtrl = namespace_correct[0]+':'+'FK_wrist_switch_'+side+'_Ctrl' FKShoulder_CTRL = namespace_correct[0]+':'+'FKShoulder_'+side+'_CTRL' temp_loc = namespace_correct[0]+':'+'temp_loc' switch_ctrl = namespace_correct[0]+':'+'FKIKArm_'+side+'_CTRL' FKElbow_CTRL = namespace_correct[0]+':'+'FKElbow_'+side+'_CTRL' FKWrist_CTRL = namespace_correct[0]+':'+'FKWrist_'+side+'_CTRL' temp_loc = pm.spaceLocator(n=temp_loc) pm.delete(pm.parentConstraint(shoulderSwitchCtrl,temp_loc)) pm.delete(pm.parentConstraint(temp_loc,FKShoulder_CTRL),temp_loc) temp_loc = pm.spaceLocator(n=temp_loc) pm.delete(pm.parentConstraint(ElbowSwitchCtrl,temp_loc)) pm.delete(pm.parentConstraint(temp_loc,FKElbow_CTRL),temp_loc) temp_loc = pm.spaceLocator(n=temp_loc) pm.delete(pm.parentConstraint(wristSwitchCtrl,temp_loc)) pm.delete(pm.parentConstraint(temp_loc,FKWrist_CTRL),temp_loc) pm.setAttr(switch_ctrl+'.FKIKBlend',0) else: print 'select switch controller',
def _hierarchyChecker(self): groups = [ 'FaceGroup', 'FaceMotionSystem', 'FaceDeformationSystem', 'FaceMotionFollowHead', 'ControlsSetup', 'RegionDeformations' ] existed = [] notExisted = [] for each in groups: if pm.objExists(each): existed.append(each) else: notExisted.append(each) if not notExisted: if len(existed) == len(groups): # parent all objects in groups. pm.parent(self.namespaceName + ':FKOffsetLips_M', 'FaceMotionFollowHead') pm.parent(self.namespaceName + ':Brs', self.namespaceName + ':Lip_Controllers', 'ControlsSetup') pm.parent(self.namespaceName + ':ClusterSetup', self.namespaceName + ':LipSetup', 'FaceMotionSystem') pm.parent(self.namespaceName + ':LipRegion', self.namespaceName + ':LipsRegion', 'RegionDeformations') pm.parent(self.namespaceName + ':faceHeadJoint', 'FaceDeformationSystem') pm.delete(self.namespaceName + ':FaceGroup') self._removeNamespace() pm.orientConstraint('Head_M', 'Brs', mo=True) ret = True else: pm.warning( 'default hierarchy is exist but not proper, please undo step and match hierarchy...' ), ret = False else: if len(notExisted) == len(groups): pm.parent(self.namespaceName + ':FaceGroup', 'Rig') self._removeNamespace() pm.orientConstraint('Head_M', 'Brs', mo=True) pm.orientConstraint('Head_M', 'FaceMotionFollowHead', mo=True) ret = True else: pm.warning( 'default hierarchy is exist but not proper, please undo step and match hierarchy...' ), ret = False if ret: if pm.objExists('Main'): pm.connectAttr('Main.s', 'Brs.s', f=True) else: pm.connectAttr('Main_CTRL.s', 'Brs.s', f=True) for each in self.controllers: pm.rename(each, each + '_CTRL') pm.setAttr('FaceDeformationSystem.v', 0) pm.setAttr('FaceDeformationSystem.v', l=True) return True else: return False
def recoverMesh(bsNode, weightIdx): """recover the blendshape target from blendshape target attribute. usually blendshape targets are deleted after editing to save disk space and save / load / calculation time. but if you need to re-edit them later, there's no option in current maya tool to do so. """ bsNode = pm.PyNode(bsNode) bsNode.envelope.set(0) aliasName = pm.aliasAttr(bsNode.weight[weightIdx], query=True) finalMeshes = pm.listFuture(bsNode, type="mesh") finalParent = None newParent = None # it is a group blendshapes if len(finalMeshes) > 1: finalParent = finalMeshes[0].getParent() if finalParent: newParent = pm.createNode('transform') pm.rename(newParent, aliasName) pm.delete(pm.parentConstraint(finalParent, newParent, mo=0)) for finalIdx, finalMesh in enumerate(finalMeshes): newMesh = pm.duplicate(finalMesh)[0] newMeshShape = newMesh.getShape() vtxDeltaList = bsNode.inputTarget[finalIdx].inputTargetGroup[ weightIdx].inputTargetItem[6000].inputPointsTarget.get() vtxIdxList = bsNode.inputTarget[finalIdx].inputTargetGroup[ weightIdx].inputTargetItem[6000].inputComponentsTarget.get() # get bs shape if vtxIdxList: # need to convert [u'vtx[8]', u'vtx[11:13]] to [8,11,12,13] singleIdxList = parseVtxIdx(vtxIdxList) for vtxIdx, moveAmount in zip(singleIdxList, vtxDeltaList): pm.move('%s.vtx[%d]' % (newMesh.name(), vtxIdx), moveAmount, r=1) newMeshShape.worldMesh[0] >> bsNode.inputTarget[ finalIdx].inputTargetGroup[weightIdx].inputTargetItem[ 6000].inputGeomTarget if newParent: pm.parent(newMesh, newParent) pm.rename(newMesh, finalMesh.name()) else: pm.rename(newMesh, aliasName) if newMesh.getParent(): pm.parent(newMesh, world=1) bsNode.envelope.set(1) if newParent: return newParent elif newMesh: return newMesh
def _export_file(self): for export_file in self.output_files: # 新建场景,打开指定场景 cmds.file(new=True, force=True) # cmds.file(export_file, o=True) cmds.file(export_file, o=True) file_name = cmds.file(q=1, sceneName=True, shortName=True).split('.')[0] print (file_name + ' already open!') defaults = ['UI', 'shared'] def num_children(ns): return ns.count(':') namespaces = [ns for ns in cmds.namespaceInfo(lon=True, r=True) if ns not in defaults] # We want to reverse the list, so that namespaces with more children are at the front of the list. namespaces.sort(key=num_children, reverse=True) for ns in namespaces: print("{}:export".format(ns)) if not pm.objExists("{}:export".format(ns)): print(u"没有找到{}:export,即将跳过循环".format(ns)) continue # todo 导入文件 # refs = cmds.ls(type='reference') # if "sharedReferenceNode" in refs: # refs.remove('sharedReferenceNode') # for i in refs: # if "_UNKNOWN_REF_NODE_" not in i: # rFile = cmds.referenceQuery(i, f=True) # print i, rFile # cmds.file(rFile, importReference=True) rFile = cmds.referenceQuery("{}RN".format(ns), f=True) print(u"即将导入文件:{}".format(rFile)) cmds.file(rFile, importReference=True) print(u"开始烘焙动画") self.bake_anim(namespace=ns) del_set = "{}:Del".format(ns) del_items = pm.sets(del_set, q=True) # 删除相关节点 for item in del_items: print(u"删除元素{}".format(item)) pm.delete(item) # todo 删除命名空间前缀 if namespaces.index(ns)+1 < len(namespaces): parent_ns = namespaces[namespaces.index(ns)+1] cmds.namespace(mv=[ns, parent_ns], f=True) cmds.namespace(rm=ns) else: cmds.namespace(mv=[ns, ":"], f=True) cmds.namespace(rm=ns) # 导出文件 if len(namespaces) > 1: output_file = "{}/{}_{}.fbx".format(self.output_path, file_name, ns) else: output_file = "{}/{}.fbx".format(self.output_path, file_name) pm.select("export") cmds.file(output_file, f=True, options="v=0;", type="FBX export", pr=True, es=True) pm.log() return
def remove(self): for child in self.transform.getChildren(): if self._pynodeIsGuidePart(child): continue child.setParent(self.transform.getParent()) pm.delete(self.transform)
def make(**kwargs): """ Makes new scaffold for auto rigger to build from. :param kwargs: name | n : `str`, Prefix name for new scaffold. length | l : `int`, Number of joints for new scaffold. socket | s : `str` or `PyNode`, Parent node for new scaffold. moduleType | mt : `str`, Module type for new scaffold (has to be implemented in \modules). includeEnd | ie : `bool`, If this scaffold, when built, should include end joint when rigging. """ name = kwargs.pop('name', kwargs.pop('n', 'untitled')) length = kwargs.pop('length', kwargs.pop('l', 1)) socket = kwargs.pop('socket', kwargs.pop('s', utils.makeRoot())) module_type = kwargs.pop('moduleType', kwargs.pop('mt', ' ')) include_end = kwargs.pop('includeEnd', kwargs.pop('ie', True)) if kwargs: raise ValueError('--Unknown argument(s): {}'.format(kwargs)) if module_type not in utils.getFilteredDir( 'modules') and module_type != ' ': raise TypeError('--Module type is invalid or not yet implemented.') if isinstance(socket, basestring): if pm.objExists(socket): socket = pm.PyNode(socket) else: raise ValueError('--Socket does not exist: {}'.format(socket)) if socket.nodeType() != 'joint': raise TypeError( '--Expected socket to be joint but got type: {}'.format( socket.nodeType())) chain = utils.makeJointChain(length, name, user.prefs['bind-skeleton-suffix']) pm.matchTransform(chain[0], socket) pm.parent(chain[0], socket) curv = pm.curve(d=1, p=data.controllerShapes['locator'], n=(name + '_display')) utils.scaleCtrlShapes(curv, scale_mult=0.5, line_width=3) shape = curv.getChildren()[0] pm.parent(shape, chain[0], r=True, s=True) pm.delete(curv) # setting colours utils.setOverrideColour(chain, c=user.prefs['default-jnt-colour']) utils.setOverrideColour(chain[0], c=user.prefs['module-root-colour']) utils.setOutlinerColour(chain[0], c=user.prefs['module-root-colour']) utils.setOverrideColour(shape, c=user.prefs['default-jnt-colour']) all_modules = utils.getFilteredDir('modules') all_modules.append(' ') default_tags = [ { 'name': 'RB_MODULE_ROOT', 'at': 'enum', 'en': ' ', 'k': 0, 'l': 1 }, { 'name': 'RB_module_type', 'k': 0, 'at': 'enum', 'en': (':'.join(all_modules)), 'dv': (all_modules.index(module_type)) }, { 'name': 'RB_include_end_joint', 'k': 0, 'at': 'bool', 'dv': include_end }, ] for tag in default_tags: utils.makeAttr(chain[0], **tag) return chain[0]
def delete_all_sound(cls): pm.delete(pm.ls(type="audio"))
def func_fix(self): for trans in self.get_all_obj_trans(): pm.delete(trans, ch=True) self.change_icon(self.button_fix, False)
def addReferenceToScene(self): """ Reference this source on the current file. If there is transformation data, it will also transform the root :return: dictionary with the new added component """ logger.info('addRefs') item = self.getItem() componentPath = item.getPublishPath() pm.createReference(componentPath, namespace=self.ns) refFile = pm.FileReference(namespace=self.ns) nodes = refFile.nodes() subRefs = pm.ls(refFile.nodes(), type='reference') for x in subRefs: nodes += x.nodes() roots = pm.ls(nodes, assemblies=True) if self.xform: if roots: n = dt.Matrix() n.setToIdentity() for transform in self.xform.itervalues(): tempNode = pm.group(empty=True) pm.xform(tempNode, m=transform['xform'], rp=transform['rotatePivot'], sp=transform['scalePivot']) m = tempNode.getMatrix() n = n * m pm.delete(tempNode) #workaround to transform groupAssets originalPar = roots[0].getParent() root = pm.group(roots) root.setTransformation(n) pm.parent(roots, originalPar) pm.delete(root) if self.onSceneParent: onSceneParentSearch = pm.ls(self.onSceneParent, r=True) if onSceneParentSearch and len(onSceneParentSearch) == 1: onSceneParent = onSceneParentSearch[0] pm.parent(roots, onSceneParent, r=True) else: logger.warn('Found no onSceneParent') newComponentDict = { 'code': self.code, 'ver': item.publishVer, 'updateMode': self.updateMode, 'task': self.task, 'proxyMode': self.proxyMode, 'xform': self.xform, 'onSceneParent': self.onSceneParent, 'assembleMode': self.assembleMode, 'type': self.type } return newComponentDict
def Finger(rootJnts=None): if not rootJnts: rootJnts = pm.ls(sl=True) else: rootJnts = pm.ls(rootJnts) for rootJnt in rootJnts: jnts = pm.listRelatives(rootJnt, ad=True) jnts.append(rootJnt) jnts.reverse() # create ctrls with zero groups for each joint ctrls = [] for i in range(len(jnts) - 1): ctrls.append( pm.curve(d=1, p=[(0, -1, 1), (0, 1, 1), (0, 1, -1), (0, -1, -1), (0, -1, 1)], k=[0, 1, 2, 3, 4], name='%s_ctrl' % jnts[i].name())) pm.delete(pm.pointConstraint(jnts[i], ctrls[i])) pm.delete(pm.orientConstraint(jnts[i], ctrls[i])) try: pm.parent(ctrls[i], ctrls[i - 1]) except: try: pm.parent(ctrls[i], world=True) except: pass # create zero groups ctrlsZerosAndOfss = ZeroGrp(ctrls) ctrlsZeros = ctrlsZerosAndOfss[0] ctrlsOfss = ctrlsZerosAndOfss[1] jntsZerosAndOfss = ZeroGrp(jnts) jntsZeros = jntsZerosAndOfss[0] jntsOfss = jntsZerosAndOfss[1] # connect transforms of ctrls to joints for i in range(len(ctrlsZeros)): ctrls[i].translate >> jntsOfss[i].translate ctrls[i].rotate >> jntsOfss[i].rotate ctrls[i].scale >> jntsOfss[i].scale # create a group for reverse scale ctrlScaleGrps = [] jntScaleGrps = [] for i in range(len(jnts) - 1): # create one for each ctrl ctrlScaleGrps.append( pm.group(em=True, name='%s_ctrl_scaleGrp' % jnts[i].name())) if i == len( jnts ): # if last joint, no need to position as where child is pm.delete(pm.pointConstraint(jnts[i], ctrlScaleGrps[i])) else: pm.delete(pm.pointConstraint(jnts[i + 1], ctrlScaleGrps[i])) pm.delete(pm.orientConstraint(jnts[i], ctrlScaleGrps[i])) # we need one more for each jnt as well jntScaleGrps.append(pm.duplicate(ctrlScaleGrps[i])[0]) pm.rename(jntScaleGrps[i], '%s_jnt_scaleGrp' % jnts[i].name()) # set hierarchy if i < len( jnts) - 2: # if last ctrl, do not parent anything under it ctrlScaleGrps[i].setParent(ctrls[i]) ctrlsZeros[i + 1].setParent(ctrlScaleGrps[i]) else: ctrlScaleGrps[i].setParent(ctrls[i]) if i < len(jnts ) - 1: # if last joint, do not parent anything under it jntScaleGrps[i].setParent(jnts[i]) jntsZeros[i + 1].setParent(jntScaleGrps[i]) # reverse the scale and connect it to next ctrlScaleGrps for i in range(len(ctrlsZeros) - 1): scaleRev = pm.createNode('multiplyDivide', name='%s_scaleRev' % ctrlsZeros[i].name()) scaleRev.input1.set(1, 1, 1) scaleRev.operation.set(2) ctrls[i].scale >> scaleRev.input2 scaleRev.output >> ctrlScaleGrps[i].scale for i in range(len(jntsZeros) - 1): scaleRev = pm.createNode('multiplyDivide', name='%s_scaleRev' % jntsZeros[i].name()) scaleRev.input1.set(1, 1, 1) scaleRev.operation.set(2) jntsOfss[i].scale >> scaleRev.input2 scaleRev.output >> jntScaleGrps[i].scale
def cylinder(parent=None, name="cylinder", width=1, heigth=1, color=[0,0,0], m=dt.Matrix(), pos_offset=None, rot_offset=None): """ Create a curve with a CYLINDER shape. Args: parent (dagNode): The parent object of the newly created curve. name (str): Name of the curve. width (float): Width of the shape. height (float): Height of the shape. color (int or list of float): The color in index base or RGB. m (matrix): The global transformation of the curve. pos_offset (vector): The xyz position offset of the curve from its center. rot_offset (vector): The xyz rotation offset of the curve from its center. xyz in radians Returns: dagNode: The newly created icon. """ dlen = width * .5 dhei = heigth * .5 # upper circle v0 = dt.Vector(0, dhei, -dlen * 1.108) v1 = dt.Vector(dlen * .78 , dhei, -dlen * .78) v2 = dt.Vector(dlen * 1.108, dhei, 0) v3 = dt.Vector(dlen * .78 , dhei, dlen * .78) v4 = dt.Vector(0, dhei, dlen * 1.108) v5 = dt.Vector(-dlen * .78 , dhei, dlen * .78) v6 = dt.Vector(-dlen * 1.108, dhei, 0) v7 = dt.Vector(-dlen * .78 , dhei, -dlen * .78) # lower circle v8 = dt.Vector(0, -dhei, -dlen * 1.108) v9 = dt.Vector(dlen * .78 , -dhei, -dlen * .78) v10 = dt.Vector(dlen * 1.108, -dhei, 0) v11 = dt.Vector(dlen * .78 , -dhei, dlen * .78) v12 = dt.Vector(0, -dhei, dlen * 1.108) v13 = dt.Vector(-dlen * .78 , -dhei, dlen * .78) v14 = dt.Vector(-dlen * 1.108, -dhei, 0) v15 = dt.Vector(-dlen * .78 , -dhei, -dlen * .78) # curves v16 = dt.Vector(0, dhei, -dlen) v17 = dt.Vector(0, -dhei, -dlen) v18 = dt.Vector(0, -dhei, dlen) v19 = dt.Vector(0, dhei, dlen) v20 = dt.Vector(dlen, dhei, 0) v21 = dt.Vector(dlen, -dhei, 0) v22 = dt.Vector(-dlen, -dhei, 0) v23 = dt.Vector(-dlen, dhei, 0) points = getPointArrayWithOffset([v0, v1, v2, v3, v4, v5, v6, v7], pos_offset, rot_offset) node = cur.addCurve(parent, name, points, True, 3, m) points = getPointArrayWithOffset([v8, v9, v10, v11, v12, v13, v14, v15], pos_offset, rot_offset) crv_0 = cur.addCurve(parent, node+"_0crv", points, True, 3, m) points = getPointArrayWithOffset([v16, v17], pos_offset, rot_offset) crv_1 = cur.addCurve(parent, node+"_1crv", points, True, 1, m) points = getPointArrayWithOffset([v18, v19], pos_offset, rot_offset) crv_2 = cur.addCurve(parent, node+"_2crv", points, True, 1, m) points = getPointArrayWithOffset([v20, v21], pos_offset, rot_offset) crv_3 = cur.addCurve(parent, node+"_3crv", points, True, 1, m) points = getPointArrayWithOffset([v22, v23], pos_offset, rot_offset) crv_4 = cur.addCurve(parent, node+"_4crv", points, True, 1, m) for crv in [crv_0, crv_1, crv_2, crv_3, crv_4]: for shp in crv.listRelatives(shapes=True): node.addChild(shp, add=True, shape=True) pm.delete(crv) setcolor(node, color) return node
def rig(self, skeleton_dict, side, region, world_space=True, control_holder_list=None, use_global_queue=False, additive=False, reverse=False, **kwargs): if not self.valid_check(skeleton_dict, side, region): return False autokey_state = pm.autoKeyframe(q=True, state=True) pm.autoKeyframe(state=False) super(ReverseFoot, self).rig(skeleton_dict, side, region, world_space, not use_global_queue, **kwargs) character_category = v1_core.global_settings.GlobalSettings( ).get_category(v1_core.global_settings.CharacterSettings) control_grp = self.create_control_grp(side, region) maya_utils.node_utils.force_align(self.skel_root, control_grp) skeleton_chain = self.network['skeleton'].get_connections() skeleton_chain = rigging.skeleton.sort_chain_by_hierarchy( skeleton_chain) rigging_chain = self.network['rigging'].get_connections() control_chain = rigging.skeleton.duplicate_chain( rigging_chain, self.namespace, 'control', self.prefix) rigging.skeleton.reverse_joint_chain(control_chain) self.network['controls'].connect_nodes(control_chain) control_root = rigging.skeleton.get_chain_root(control_chain) control_root.setParent(control_grp) rigging_chain = rigging.skeleton.sort_chain_by_hierarchy(rigging_chain) control_chain = rigging.skeleton.sort_chain_by_hierarchy(control_chain) control_chain.reverse() toe_joint = skeleton_chain[-3] toe_children = toe_joint.getChildren(type='joint') toe_ik_joint = get_first_or_default( [x for x in toe_children if x not in skeleton_chain]) toe_ik_control = None if toe_ik_joint: toe_ik_control = get_first_or_default(pm.duplicate(toe_ik_joint)) toe_ik_control.rename(self.namespace + 'control_' + toe_ik_joint.name()) toe_ik_control.setParent(get_index_or_default(control_chain, -3)) self.network['controls'].connect_node(toe_ik_control) control_chain_start = get_first_or_default(control_chain) control_chain_end = get_last_or_default(control_chain) # Orient heel joint to world space if character_category.world_orient_ik: control_chain[1].setParent(None) control_chain_start.setParent(None) control_chain_start.jointOrient.set([0, 0, 0]) control_chain_start.rotate.set([0, 0, 0]) pm.delete( pm.aimConstraint(toe_joint, control_chain_start, aim=[0, -1, 0], upVector=[0, 0, 1], wut="scene", mo=False)) control_chain_start.setParent(control_grp) control_chain[1].setParent(control_chain_start) delete_chain = rigging_chain[:-3] rigging_chain = rigging_chain[-3:] pm.delete(delete_chain) # toe_ik will be inserted as index 0 (in place of the attach jonit) if it exists, if it doesn't we want to # move all control indicies up 1 since we don't allow control of the attach joint index_offset = -1 if toe_ik_joint: index_offset = 0 rigging.skeleton.force_set_attr(toe_ik_joint.visibility, False) rigging.skeleton.force_set_attr(toe_ik_control.visibility, True) self.create_controls([toe_ik_control], side, region, 'toe_ik', control_holder_list) self.create_controls(control_chain, side, region, 'reverse_fk', control_holder_list, index_offset) control_property = metadata.meta_properties.get_property( control_chain_start, metadata.meta_properties.ControlProperty) control_property.set('world_space', True, 'bool') for i, child_control in enumerate(control_chain[:-1]): pm.controller([control_chain[i + 1], child_control], p=True) ball_ik_handle, end_effector = pm.ikHandle( sj=rigging_chain[2], ee=rigging_chain[1], sol='ikSCsolver', name="{0}{1}_{2}_rv_ball_ikHandle".format(self.namespace, side, region)) ball_ik_handle.setParent(control_chain[-2]) rigging.skeleton.force_set_attr(ball_ik_handle.visibility, False) toe_ik_handle, end_effector = pm.ikHandle( sj=rigging_chain[1], ee=rigging_chain[0], sol='ikSCsolver', name="{0}{1}_{2}_rv_toe_ikHandle".format(self.namespace, side, region)) ik_parent = toe_ik_control if toe_ik_joint else control_chain[-3] toe_ik_handle.setParent(ik_parent) rigging.skeleton.force_set_attr(toe_ik_handle.visibility, False) control_chain_end.rename(control_chain_end + "_attach") self.network['attachment'].connect_node(skeleton_chain[-1]) for control in control_chain[:-1]: rigging.skeleton.force_set_attr(control.visibility, True) rigging.skeleton.force_set_attr(control_chain_end.visibility, False) rigging.skeleton.force_set_attr(skeleton_chain[-3].visibility, False) rigging.skeleton.force_set_attr(rigging_chain[-1].visibility, False) rigging.constraints.bind_chains([control_chain_end], [rigging_chain[2]], self.exclude) self.attach_component(True) if rigging.skeleton.is_animated(skeleton_chain): self.attach_and_bake(self.skeleton_dict, use_global_queue) if not use_global_queue: rigging.skeleton.remove_animation(skeleton_chain) if use_global_queue: if not additive: maya_utils.baking.Global_Bake_Queue().add_post_process( self.save_animation, {}) maya_utils.baking.Global_Bake_Queue().add_post_process( self.bind_chain_process, { 'skeleton_chain': skeleton_chain, 'rigging_chain': rigging_chain }) else: if not additive: self.save_animation() self.bind_chain_process(skeleton_chain, rigging_chain) pm.autoKeyframe(state=autokey_state) return True