def bdClustersOnCurve(self,curveDrv,segments): clusters = [] curveCVs = curveDrv.cv topClusterTransform= pm.cluster([curveCVs[0],curveCVs[1]],rel=True)[1] topClusterTransform.rename(curveDrv.name() + '_top_CLS') topClusterTransform.getShape().originY.set(segments * 0.5) pivot = curveCVs[0].getPosition(space='world') topClusterTransform.setPivots(pivot) clusters.append(topClusterTransform) midClusterTransform = pm.cluster(curveCVs[1],rel=True)[1] midClusterTransform.rename(curveDrv.name() + '_mid_CLS') pivot = curveCVs[1].getPosition(space='world') midClusterTransform.setPivots(pivot) clusters.append(midClusterTransform) botClusterTransform = pm.cluster([curveCVs[1],curveCVs[2]],rel=True)[1] botClusterTransform.rename(curveDrv.name() + '_bot_CLS') botClusterTransform.getShape().originY.set(segments * - 0.5 ) pivot = curveCVs[2].getPosition(space='world') botClusterTransform.setPivots(pivot) clusters.append(botClusterTransform) topCluster = topClusterTransform.listConnections(type='cluster')[0] botCluster = botClusterTransform.listConnections(type='cluster')[0] pm.percent(topCluster,curveCVs[1],v=0.5) pm.percent(botCluster,curveCVs[1],v=0.5) clsGrp = pm.group(clusters,n=curveDrv.name() + '_CLS_GRP') return clusters,clsGrp
def transfer_shape(source, target, snap_to_target=True, fix_name=False): """ Reparent a shape node from one parent to another @param source: The source dag which contains the shape @param target: The source dag which will have the new shape the shape @param snap_to_target: Should be we reparent with world space or object space @param fix_name: Should we match the name of the shape to the new target @return: """ source = force_pynode(source) target = force_pynode(target) if snap_to_target: snap(source, target) pm.makeIdentity(source, apply=1) if source.getShape().type() != "locator": try: pm.cluster(source) pm.delete(source, ch=1) except RuntimeError: logger.warning("Cannot cluster {}".format(source)) oldShape = source.getShape() pm.parent(oldShape, target, shape=1, relative=1) if fix_name: fix_shape_name(target) return oldShape
def setCVInfo(ctrlInfo): """Restore CV shapes based on the list of name and position dictionary @param ctrlInfo: list of dictionary with name of the node and positions of CVs """ for ctrl in ctrlInfo: if pm.objExists(ctrl): CVs = ctrlInfo[ctrl] ctrl = pm.PyNode(ctrl) ctrl.setCVs(CVs, space="object") pm.cluster(ctrl) pm.delete(ctrl, constructionHistory = True)
def create_radian_trigger(prefix): prefix = ("%s_radianTrigger") %prefix display = pm.group(empty=True, name="%s_display" %prefix) display.overrideEnabled.set(1) display.overrideDisplayType.set(2) grp = pm.group(empty=True, name="%s_grp" %prefix) loc = pm.spaceLocator(name = "%s_target" %prefix) pm.addAttr(loc, at='double', ln="radical", k=True) pm.addAttr(loc, at='double', ln="angle", k=True) pos = pm.spaceLocator(name = "%s_pos" %prefix) loc.ty.set(1) loc.tz.set(1) pos.tz.set(1) radical_exp = '%s.radical = rad_to_deg( atan2( %s.translateY , %s.translateX ) )' %(loc.name(), loc.name(), loc.name()) angle_exp = "%s.angle = rad_to_deg( acos( %s.translateZ / (sqrt( pow(%s.translateX, 2) + pow(%s.translateY, 2) + pow(%s.translateZ, 2) ) ) ) )" %(loc.name(), loc.name(), loc.name(), loc.name(), loc.name()) pm.expression( o=loc, s= radical_exp, name="%s_radical_exp" %prefix) pm.expression( o=loc, s= angle_exp, name="%s_angle_exp" %prefix) planer_curve = "curve -d 1 -p 0 0 0 -p -1 0 0 -p -0.965926 0.258819 0 -p -0.765926 0.258819 0 -p -0.865926 0.258819 0 -p -0.865926 0.358819 0 -p -0.865926 0.158819 0 -p -0.865926 0.258819 0 -p -0.965926 0.258819 0 -p -0.866025 0.5 0 -p -0.707107 0.707107 0 -p -0.353553 0.353553 0 -p -0.707107 0.707107 0 -p -0.5 0.866025 0 -p -0.258819 0.965926 0 -p 0 1 0 -p 0 0.5 0 -p 0 1 0 -p 0.258819 0.965926 0 -p 0.5 0.866025 0 -p 0.707107 0.707107 0 -p 0.353553 0.353553 0 -p 0.707107 0.707107 0 -p 0.866025 0.5 0 -p 0.965926 0.258819 0 -p 1 0 0 -p 0.5 0 0 -p 1 0 0 -p 0.965926 -0.258819 0 -p 0.866025 -0.5 0 -p 0.707107 -0.707107 0 -p 0.353553 -0.353553 0 -p 0.707107 -0.707107 0 -p 0.5 -0.866025 0 -p 0.258819 -0.965926 0 -p 0 -1 0 -p 0 -0.5 0 -p 0 -1 0 -p -0.258819 -0.965926 0 -p -0.5 -0.866025 0 -p -0.707107 -0.707107 0 -p -0.353553 -0.353553 0 -p -0.707107 -0.707107 0 -p -0.866025 -0.5 0 -p -0.965926 -0.258819 0 -p -0.765926 -0.258819 0 -p -0.965926 -0.258819 0 -p -1 0 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 -k 6 -k 7 -k 8 -k 9 -k 10 -k 11 -k 12 -k 13 -k 14 -k 15 -k 16 -k 17 -k 18 -k 19 -k 20 -k 21 -k 22 -k 23 -k 24 -k 25 -k 26 -k 27 -k 28 -k 29 -k 30 -k 31 -k 32 -k 33 -k 34 -k 35 -k 36 -k 37 -k 38 -k 39 -k 40 -k 41 -k 42 -k 43 -k 44 -k 45 -k 46 -k 47" planer = pm.PyNode(pm.mel.eval(planer_curve)) planer.rename("%s_planer" %prefix) arrow_curve = 'curve -d 1 -p 0 0 0 -p 0 0.377909 0 -p -0.0449662 0.378085 0 -p 0 0.460303 0 -p 0.0449662 0.378085 0 -p 0 0.377909 0 -k 0 -k 1 -k 2 -k 3 -k 4 -k 5 ;' arrow = pm.PyNode(pm.mel.eval(arrow_curve)) pm.makeIdentity(arrow, apply=True, t=True, r=True, s=True) arrow.rename("%s_arrow" %prefix) angle_curves = pm.circle(name="%s_angleCurve" %prefix, r=0.5) pm.aimConstraint(pos, angle_curves[0], mo=False, aimVector=[0,1,0], upVector=[-1,0,0], worldUpType='object', worldUpObject=loc) pm.parent(arrow, angle_curves) loc.angle >> angle_curves[-1].sweep posPointer = pm.curve(name='%s_posPointer'%prefix, d = 1, p = [(0,0,0), (0,0,1)]) pointer = pm.curve(name='%s_targetPointer'%prefix, d = 1, p = [(0,0,0), (0,0,0)]) pointer.inheritsTransform.set(0) cls1 = pm.cluster(pointer.cv[0], name='%s_pointerClusterStart' %prefix) cls2 = pm.cluster(pointer.cv[1], name='%s_pointerClusterEnd' %prefix) pm.parent(pos, planer, angle_curves[0], cls1, pointer, posPointer, display) pm.parent(display, loc, grp) pm.parent(cls2, loc, r=True) cls1[1].v.set(0) cls2[1].v.set(0) pos.v.set(0)
def create_BTN_pressed(self): ctrl_suffix = self.widgets['suffix_TFG'].getText() create_offsetNode = self.widgets['offsetNode_CB'].getValue() offsetNode_suffix = self.widgets['offsetNode_TF'].getText() create_cluster = self.widgets['cluster_CB'].getValue() cluster_group = self.widgets['clusterGroup_RBG'].getSelect() create_shape = self.widgets['shape_CB'].getValue() shape_type = self.widgets['shape_TSL'].getSelectItem()[0] shape_axis = self.widgets['shapeAxis_OM'].getValue() hierarchy = self.widgets['hierarchry_RB'].getSelect() tConst = self.widgets['tConst_CB'].getValue() rConst = self.widgets['rConst_CB'].getValue() pConst = self.widgets['pConst_CB'].getValue() sConst = self.widgets['sConst_CB'].getValue() clusterHandles = [] if create_cluster: if cluster_group == 1: #each for obj in pm.selected(): c, hdl = pm.cluster(obj, name='%s_cluster'%obj.name()) clusterHandles.append(hdl) elif cluster_group == 2: #all c, hdl = pm.cluster(pm.selected()) clusterHandles.append(hdl) ctrls = [] objects = clusterHandles or pm.selected() for i, obj in enumerate(objects): ctrlName = "%s_%s" %(obj.name(), ctrl_suffix) ctrl = obj.add_ctrl(name=ctrlName, point=tConst, orient=rConst, scale=sConst, parent=pConst) ctrls.append(ctrl) if hierarchy == 2 and i != 0: #selectionOrder pm.parent(ctrl, ctrls[ i-1 ]) if create_offsetNode: ctrl.add_parent_group(suffix=offsetNode_suffix) if create_shape: ctrl.add_shape(shape=shape_type, axis=shape_axis)
def createCluster(vertexs, name): mesh = vertexs[0].node() cluster = pm.cluster(mesh, name="{0}_Clu".format(name)) pm.percent(cluster[0], mesh.vtx, v=0) pm.percent(cluster[0], vertexs, v=1) cluster[-1].visibility.set(0) return cluster
def build(self): super(CurveDeformer, self).build() oCurve = next((o for o in self.input if any (s for s in o.getShapes() if isinstance(s, pymel.nodetypes.NurbsCurve))), None) oSurface = next((o for o in self.input if any (s for s in o.getShapes() if isinstance(s, pymel.nodetypes.NurbsSurface))), None) if self.type == self.kType_NurbsSurface: oSurface = _createNurbsSurfaceFromNurbsCurve(oCurve) oSurface.rename(self._pNameMapRig.Serialize()+'_nurbsSurface') oSurface.setParent(self.grp_rig) for i in range(oSurface.numKnotsInV()-1): cluster, clusterHandle = pymel.cluster(oSurface.cv[0:3][i]) cluster.rename(self._pNameMapRig.Serialize('cluster', _iIter=i)) clusterHandle.rename(self._pNameMapRig.Serialize('clusterHandle', _iIter=i)) clusterHandle.setParent(self.grp_rig) uRef = pymel.createNode('transform') uRef.rename(self._pNameMapRig.Serialize('cvRef', _iIter=i)) uRef.setParent(self.grp_rig) pymel.connectAttr(oCurve.controlPoints[i], uRef.t) #pymel.connectAttr(libRigging.CreateUtilityNode('pointOnCurveInfo', inputCurve=oCurve.worldSpace, parameter=((float(i)/(oSurface.numKnotsInV()-3)))).position, uRef.t) #pymel.tangentConstraint(oCurve, uRef) clusterHandle.setParent(uRef) assert(isinstance(oSurface, pymel.PyNode)) self.aJnts = _createSurfaceJnts(oSurface, self.numJnts) for i, jnt in enumerate(self.aJnts): jnt.rename(self._pNameMapRig.Serialize(_iIter=i)) jnt.setParent(self.grp_rig)
def create(ctl, tipGeo, weights, name, keys, addGeos=[], useScale=False): ''' tipGeo - vtx of the tip of the eye weights - list of weights for each loop radiating outwards (including geoTip) e.g. [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1] addGeo - list of additional geometry for cluster to deform name - 'pupil' or 'iris' e.g.: geo = nt.Mesh(u'LT_eyeball_geoShape') tipGeo = geo.vtx[381] ctl = nt.Transform(u'LT_eye_ctl') name = '_iris' keys = {'sx': {0.01:0.01, 1:1, 2:2}, 'sy': {0.01:0.01, 1:1, 2:2}, 'sz': {0.01:0.01, 1:1, 2:3.75}} weights = [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1] ''' geo = tipGeo.node() dfm, hdl = pm.cluster(tipGeo, n=ctl+name+'_dfm', foc=True) dfg = pm.group(hdl, n=ctl+name+'_dfg') rp = hdl.getRotatePivot(space='world') sp = hdl.getScalePivot(space='world') dfg.setRotatePivot(rp, space='world') dfg.setScalePivot(sp, space='world') dfh = pm.group(dfg, n=ctl+name+'_dfh') ctl.addAttr(name, min=0.01, max=2, dv=1, k=True) for attr, key in keys.items(): rt.connectSDK(ctl.attr(name), hdl.attr(attr), key) loopNums = len(weights) - 1 vertLoops = mesh.VertexLoops([tipGeo], loopNums) # add membership pm.select(vertLoops[:]) for vertLoop in vertLoops[:]: for eachVert in vertLoop: dfm.setGeometry(eachVert) for loopId, weight in enumerate(weights): for eachVert in vertLoops[loopId]: print eachVert dfm.setWeight(geo, 0, eachVert, weight) # add additional geometries for eachGeo in addGeos: dfm.setGeometry(eachGeo, foc=True) if useScale: # modulate cluster scale by control scale for eachAttr in ('sx', 'sy', 'sz'): scaleInput = hdl.attr(eachAttr).inputs(p=True)[0] mdl = pm.createNode('multDoubleLinear', n=hdl+'_'+eachAttr+'_scale_mdl') scaleInput >> mdl.input1 ctl.attr(eachAttr) >> mdl.input2 mdl.output >> hdl.attr(eachAttr) return dfh
def main(**kwargs): import pymel.core as pm c = pm.cluster(pm.selected()) loc = pm.spaceLocator() pm.delete(pm.pointConstraint(c, loc, mo=False)) pm.delete(c)
def get_centre_piv_pos(geo): """ Get the center point of a geo with help of cluster @param geo: The target geo """ cluster = pm.cluster(geo)[1] pos = pm.xform(cluster) pm.delete(cluster) return pos
def convert_joint_to_cluster(targetGeo, skipList=[]): """ Convert a skin cluster to a cluster based setup on a target geometery @param targetGeo: the geometery which has the skin cluster @param skipList: any joints which should not processed such as a base joint @return A dictonary of cluster with the name of the joints as keys """ # Convert to PyNode targetGeo = pm.PyNode(targetGeo) skin = libUtilities.get_target_defomer(targetGeo, "skinCluster") # Create the dictionary clusterInfo = {} # Progress Info pm.progressWindow(title='Converting Skin To Cluster', progress=0, status='Progress: 0%') totalJnts = len(skin.getInfluence()) - len(skipList) currentJnt = 0.0 # Go through Each Joint for jnt in sorted(skin.getInfluence()): if jnt.name() in skipList: continue # Get the vertex affected and the weight vertZip, weightList = skin.getPointsAffectedByInfluence(jnt) if not vertZip: raise Exception("Current Joint Has No Vertices:%s" % jnt) pm.select(vertZip) # Iterate through selection and decompress vertic group into individual index vertices = libUtilities.indexize_vertice_group(pm.selected()) # Select Vertices libUtilities.select_vertices(targetGeo, vertices) # Make a cluster cltr, cTransform = pm.cluster(rel=1) jntPos = pm.xform(jnt, q=1, ws=1, rp=1) pm.setAttr(cTransform.scalePivot, jntPos) pm.setAttr(cTransform.rotatePivot, jntPos) # Set the weight for index, weight in zip(vertices, weightList): cltr.weightList[0].weights[index].set(weight) # Add to dictionary clusterInfo[jnt.name()] = {"cluster": cltr, "clusterHandle": cTransform} # Update Progress currentJnt = currentJnt + 1.0 currentProgress = (currentJnt / totalJnts) * 100 pm.progressWindow(edit=True, progress=currentProgress, status=('Progress: ' + str(int(currentProgress)) + '%')) pm.refresh() pyLog.info("Converted: " + jnt.name()) pm.progressWindow(endProgress=1) return clusterInfo
def clusLoc(): '''create a clus base on edges''' #sl edges edges = pm.selected(flatten = True) #convert to edges verts = list(set(sum([list(e.connectedVertices()) for e in edges],[]))) #create clus clusShp,clusTras = pm.cluster(verts) loc = pm.spaceLocator() pcn = pm.pointConstraint(clusTras,loc, mo = False) pm.delete(pcn) pm.delete(clusTras)
def rig_clusterCurve(crv, ends=False, relative=True): ''' Clusters a curve based on CVs Args: crv (pm.nt.NurbsCurve): curve to be modified ends (boolean): if we want the two in front and back to be one cluster Returns list(pm.nt.Cluster): list of clusters created ''' #rig_clusterCurve(pm.ls(sl=True)[0], ends=True) clusters=[] for cv in range(0,crv.getShape().numCVs()-1): clstrName = '%s_cv%d'%(crv.name(),len(clusters)) if ends: if cv == 0: clusters.append( pm.cluster( crv.getShape().cv[cv:cv+1], rel=relative, n=clstrName )) elif cv == 1: None elif cv == crv.getShape().numCVs() - 2: clusters.append( pm.cluster( crv.getShape().cv[cv:cv+1], rel=relative, n=clstrName )) else: clusters.append( pm.cluster( crv.getShape().cv[cv], rel=relative, n=clstrName )) else: clusters.append( pm.cluster( crv.getShape().cv[cv], rel=relative, n=clstrName ) ) return clusters
def clusLoc(): """ puts a locator at a controid position in a ring of edges""" edges = pm.selected(flatten = True) verts = list(set(sum( [list(e.connectedVertices()) for e in edges], []) ) ) # CLUSTER clusDef, clustTfm = pm.cluster(verts) # LOCATOR loc = pm.spaceLocator() # POINT CONSTRAINT pm.delete( pm.pointConstraint(clustTfm, loc, mo = False))
def shell_clusterCreate(shellVerts, surface): '''Creates a cluster based on the shell and makes the pivot the closest vert to the surface Args: shellVerts (list of pm.nt.MeshVertex): list of verts for the shell surface (pm.PyNode): surface to use as rider Returns (list of pm.nt.Cluster): clusters that were created Usage: shell_clusterCreate(getShell(pm.ls(sl=True)[0]), pm.PyNode('pSphere1')) ''' pivot = closestPoint(shellVerts, surface).getPosition() cluster = pm.cluster(shellVerts) cluster[1].rotatePivot.set( pivot ) cluster[1].scalePivot.set( pivot ) return cluster
def clusterEdgeIslands(edges): ''' Args: edges (list(pm.nt.general.MeshEdge)): edges to be clustered Returns (list(pm.nt.Transform)): list of cluster transforms Usage: clusterEdgeIslands(pm.ls(sl=True,fl=True)) ''' transform = edges[0].node().getParent() islands = getEdgeIslands(edges) clusters = [] for index, island in enumerate(islands): islandVerts = pm.ls( pm.polyListComponentConversion(island, tv=True), fl=True ) clusters.append( pm.cluster(islandVerts,n=transform.replace('GEO','%02d_CLUSTER'%index)) ) return clusters
def locAtCenter(*args): if args: pm.select(args) sel = pm.ls(sl=True, fl=True) if not sel : return pm.select(sel) pm.mel.ConvertSelectionToVertices() clst = pm.cluster() loc = pm.spaceLocator() pm.pointConstraint(clst,loc) pm.delete(clst) return loc
def process(self, context, plugin): import pymel.core as pm # Get the errored instances failed = [] for result in context.data["results"]: if (result["error"] is not None and result["instance"] is not None and result["instance"] not in failed): failed.append(result["instance"]) # Apply pyblish.logic to get the instances for the plug-in instances = api.instances_by_plugin(failed, plugin) for instance in instances: for node in instance[0].members(): pm.delete(pm.cluster(node))
def _create_deformers_(self): # Build in the order of the clusters for cluster in libXml.list_persist(self.import_data["Order"]): if not pm.objExists(cluster): # Read info for each cluster info = self.import_data["Data"][cluster] # select vertices libUtilities.select_vertices(self.target, libXml.list_persist(info["Vertices"])) # Create the cluster cltr, cTransform = pm.cluster(rel=info["Relative"]) # Set the pivot pm.setAttr(cTransform.scalePivot, info["ScalePivot"]) pm.setAttr(cTransform.rotatePivot, info["RotatePivot"]) # Rename cTransform.rename(info["ClusterHandleName"]) cltr.rename(cluster)
def SetupIconScale(self, _animationModuleNamespace): clusterNodes = pm.cluster(self.controlObject, name = "%s_icon_scale_cluster" %self.controlObject, relative = True) pm.container("%s:module_container" %_animationModuleNamespace, edit = True, addNode = clusterNodes, includeHierarchyBelow = True, includeShapes = True) clusterHandle = clusterNodes[1] pm.setAttr("%s.scalePivotX" %clusterHandle, 0) pm.setAttr("%s.scalePivotY" %clusterHandle, 0) pm.setAttr("%s.scalePivotZ" %clusterHandle, 0) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleX" %clusterHandle) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleY" %clusterHandle) pm.connectAttr("%s:module_grp.iconScale" %_animationModuleNamespace, "%s.scaleZ" %clusterHandle) pm.parent(clusterHandle, self.controlObject, absolute = True) pm.setAttr("%s.visibility" %clusterHandle, 0)
def soft_cluster(): ''' Converts a soft selection into a cluster Args: None Returns (pm.nt.Cluster): generated cluster Usage: soft_cluster() ''' selection = pm.ls(sl=True) # Rich selection list includes soft selection richSel = om.MRichSelection() om.MGlobal.getRichSelection(richSel) richSelList = om.MSelectionList() richSel.getSelection(richSelList) # Setup the pointers for the paths path = om.MDagPath() component = om.MObject() cluster = pm.cluster( rel=True ) clusterSet = pm.listConnections( cluster, type="objectSet" )[0] richSelList.getDagPath(1, path) for o_index in range(0, richSelList.length()): object_path = om.MDagPath() richSelList.getDagPath(o_index, object_path) shape = pm.PyNode(object_path.fullPathName()) richSelList.getDagPath(o_index, path, component) # Get the components componentFn = om.MFnSingleIndexedComponent(component) for i in range(0,componentFn.elementCount()): weight = componentFn.weight(i) v = componentFn.element(i) w = weight.influence() #print "The selection weight of vertex %d is %f." % (v, w) vtx = (shape.name()+'.vtx[%d]') % v pm.sets(clusterSet, add=vtx) pm.percent(cluster[0], vtx, v=w) pm.select(cluster) return cluster
def build_nurbs_between_points(xformA, xformB, ref_xform, spansUV=[1,4]): """ Build a simple nurbs surface between two points with a surface up third object Args: xformA (pm.nt.Transform): first point xformB (pm.nt.Transform): second point ref_xform (pm.nt.Transform): aim object Usage: Mesh.build_nurbs_between_points(pm.PyNode('locator1'),pm.PyNode('locator2'),pm.PyNode('locator3')) """ nurbs = pm.nurbsPlane(p=[0,0,0], ax=[0,1,0], w=1, lr=1, d=1, u=1, v=1, ch=0)[0] nurbs.scalePivot.set(0,0,0.5) nurbs.rotatePivot.set(0,0,0.5) pm.delete(pm.pointConstraint(xformA, nurbs, mo=False)) pm.delete(pm.aimConstraint(xformB, nurbs, worldUpType=1, aimVector=[0,0,-1], worldUpVector=[0,1,0], worldUpObject=ref_xform, mo=False)) cluster = pm.cluster(nurbs.getShape().cv[0:1][1]) pm.delete(pm.pointConstraint(xformB, cluster, mo=False)) pm.delete(nurbs, ch=True) u, v = spansUV pm.rebuildSurface(nurbs.getShape(), ch=False, rpo=1, rt=0, end=1, kr=0, kcp=0, kc=0, su=u, du=3, sv=v, dv=3, tol=0, fr=0, dir=2) return nurbs
def build_cluster_crv(self, *args): """ builds a curve with 3 cv's controled by clusters Args: None Returns (None) """ crv_name = self.flexiPlaneNameField.getText() + '_flexiPlane_wire_CRV' surf_bShp_name = self.flexiPlaneNameField.getText() + '_flexiPlane_bShp_SURF' clusterA_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustA_CL' clusterB_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustB_CL' clusterC_name = self.flexiPlaneNameField.getText() + '_flexiPlane_clustC_CL' clusterGRP_name = self.flexiPlaneNameField.getText() + '_flexiPlane_CLSTR_GRP' surf_bShpGRP_name = self.flexiPlaneNameField.getText() + '_flexiPlane_bShp_GRP' num_jnts_slider = self.flexiPlaneNumSlider.getValue() cvA_pos = num_jnts_slider * -1 cvC_pos = num_jnts_slider pm.curve( n = crv_name, d = 2, p = [( cvA_pos, 0, 0 ), ( 0, 0, 0 ), ( cvC_pos, 0, -0 )], k = [0, 0, 1, 1] ) pm.select( crv_name +'.cv[0:1]', r = True ) pm.cluster( n = clusterA_name, en = 1, rel = True ) pm.setAttr( clusterA_name + 'Handle.originX', cvA_pos ) pm.move( cvA_pos, 0, 0, clusterA_name + 'Handle.scalePivot', clusterA_name + 'Handle.rotatePivot', ws = True ) pm.select( crv_name +'.cv[1:2]', r = True ) pm.cluster( n = clusterC_name, en = 1, rel = True ) pm.setAttr( clusterC_name + 'Handle.originX', cvC_pos ) pm.move( cvC_pos, 0, 0, clusterC_name + 'Handle.scalePivot', clusterC_name + 'Handle.rotatePivot', ws = True ) pm.select( crv_name +'.cv[1]', r = True ) pm.cluster( n = clusterB_name, en = 1, rel = True ) pm.select( crv_name +'.cv[1]', r = True ) pm.percent( clusterA_name, crv_name +'.cv[1]', v = 0.5 ) pm.percent( clusterC_name, crv_name +'.cv[1]', v = 0.5 ) pm.group( em = True, name = clusterGRP_name ) pm.parent(clusterA_name + 'Handle', clusterGRP_name ) pm.parent(clusterB_name + 'Handle', clusterGRP_name ) pm.parent(clusterC_name + 'Handle', clusterGRP_name ) pm.parent(clusterGRP_name, surf_bShpGRP_name )
def clusLoc(): """ create locator at a centroid position in a ring of edges how to use: select edges loop and excute this command from rigWorkshop.ws_user.jun.utils import clusLoc reload(clusLoc) clusLoc.clusLoc() """ edges = pm.selected(flatten=True) #list comprehension verts = list(set(sum([list(e.connectedVertices()) for e in edges], []))) #cluster clusDFM, clusTRN = pm.cluster(verts) #locator loc = pm.spaceLocator() #point constraint pm.delete(pm.pointConstraint(clusTRN, loc, mo=False)) pm.delete(clusTRN)
def weighted_cluster(target_geo, vertices, weight_list, joint_position): """ Created a relative weighted cluster @param target_geo: The geo which will get the cluster @param vertices: The vertices which form the cluster @param weight_list: The weight map for the cluster @param joint_position: The pivot of the cluster @return: The created transform and cluster node """ libUtilities.select_vertices(target_geo, vertices) # Make a cluster cltr, cTransform = pm.cluster(rel=1, foc=True) pm.setAttr(cTransform.scalePivot, joint_position) pm.setAttr(cTransform.rotatePivot, joint_position) # Set the weight for index, weight in zip(vertices, weight_list): cltr.weightList[0].weights[index].set(weight) # Set the weight for index, weight in zip(vertices, weight_list): cltr.weightList[0].weights[index].set(weight) return {"cluster": cltr, "clusterHandle": cTransform}
def create(cls, geometry, influences=None): cluster = pm.cluster(geometry)[1] return Cluster(cluster)
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 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 guide( description, side, parent=None, xform=None, translation_offset=None, rotation_offset=None, match_to=None, link_to=None, shape=None, ): """ Creates a control structure - which is a structure which conforms to the following hierarchy: ORG -> ZRO -> OFF -> CTL :param description: Descriptive section of the name :type description: str :param side: Tag for the location to be used during the name generation :type side: str :param parent: Optional parent to assign to the node :type parent: pm.nt.DagNode :param xform: Optional worldSpace matrix to apply to the object :type xform: pm.dt.Matrix :param match_to: Optional node to match in worldspace :type match_to: pm.nt.DagNode :param shape: Optional shape to apply to the node :type shape: name of shape or path :param link_to: If given, an unselectable line is drawn between this guide control and the given transform. :type link_to: pm.nt.DagNode :return: pm.nt.DependNode """ guide_node = generic( 'transform', config.GUIDE, description, side, shape=shape or 'cube', parent=parent, xform=xform, match_to=match_to or parent, ) if link_to: curve = pm.curve( d=1, p=[ [0, 0, 0], [0, 0, 0], ], ) # -- Make the curve unselectable curve.getShape().template.set(True) # -- Create the first cluster pm.select('%s.cv[0]' % curve.name()) cls_root_handle, cls_root_xfo = pm.cluster() # -- Create the second cluster pm.select('%s.cv[1]' % curve.name()) cls_target_handle, cls_target_xfo = pm.cluster() # -- Hide the clusters, as we do not want them # -- to be interactable cls_root_xfo.visibility.set(False) cls_target_xfo.visibility.set(False) # -- Ensure they're both children of the guide cls_root_xfo.setParent(guide_node) cls_target_xfo.setParent(guide_node) # -- Ensure the target is zero'd cls_target_xfo.setMatrix(pm.dt.Matrix()) # -- Constrain the root to the linked object pm.parentConstraint( link_to, cls_root_xfo, maintainOffset=False, ) # -- Set the guide specific colouring guide_node.useOutlinerColor.set(True) guide_node.outlinerColorR.set(config.GUIDE_COLOR[0] * (1.0 / 255)) guide_node.outlinerColorG.set(config.GUIDE_COLOR[1] * (1.0 / 255)) guide_node.outlinerColorB.set(config.GUIDE_COLOR[2] * (1.0 / 255)) # -- Set the display colour for guide_shape in guide_node.getShapes(): guide_shape.overrideEnabled.set(True) guide_shape.overrideRGBColors.set(True) guide_shape.overrideColorR.set(config.GUIDE_COLOR[0] * (1.0 / 255)) guide_shape.overrideColorG.set(config.GUIDE_COLOR[1] * (1.0 / 255)) guide_shape.overrideColorB.set(config.GUIDE_COLOR[2] * (1.0 / 255)) if translation_offset: guide_node.setTranslation( translation_offset, worldSpace=False, ) if rotation_offset: guide_node.setRotation( rotation_offset, worldSpace=False, ) return guide_node
def __init__(self, spineJoints, rootJnt, prefix='spine', rigScale=1.0, baseRig=None, bodyLocator='', chestLocator='', pelvisLocator=''): """ :param spineJoints: list( str ), list of 6 spine joints :param rootJnt: str, root joint :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: instance of base.module.Base class :param bodyLocator: str, reference transform for position of body control :param chestLocator: str, reference transform for position of chest control :param pelvisLocator: str, reference transform for position of pelvis control :return: dictionary with rig module objects """ # :param spineCurve: str, name of spine cubic curve with 5 CVs matching first 5 spine joints # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # control locator reference position if bodyLocator == '' or chestLocator == '' or pelvisLocator == '': pass bodyLocator, chestLocator, pelvisLocator = self.makeControlLocatorReferencePosition( spineJoints) # make IK handle spineIk, effector, spineCurve = pm.ikHandle( n=prefix + '_IKH', sol='ikSplineSolver', sj=spineJoints[0], ee=spineJoints[-1], # -2 createCurve=True, numSpans=2) # rename curve pm.rename(spineCurve, prefix + '_CRV') # make spine curve clusters spineCurveCVs = pm.ls(spineCurve + '.cv[*]', fl=1) numSpineCVs = len(spineCurveCVs) spineCurveClusters = [] for i in range(numSpineCVs): cls = pm.cluster(spineCurveCVs[i], n=prefix + 'Cluster%d' % (i + 1))[1] spineCurveClusters.append(cls) pm.hide(spineCurveClusters) # parent spine curve pm.parent(spineCurve, self.rigmodule.partsNoTransGrp) # make controls self.bodyCtrl = control.Control(prefix=prefix + 'Body', translateTo=bodyLocator, rotateTo=spineJoints[-1], scale=rigScale * 4, parent=self.rigmodule.controlsGrp, shape='spine') chestCtrl = control.Control(prefix=prefix + 'Chest', translateTo=chestLocator, rotateTo=spineJoints[-1], scale=rigScale * 6, parent=self.bodyCtrl.C, shape='chest') pelvisCtrl = control.Control(prefix=prefix + 'Pelvis', translateTo=pelvisLocator, rotateTo=pelvisLocator, scale=rigScale * 6, parent=self.bodyCtrl.C, shape='hip') middleCtrl = control.Control(prefix=prefix + 'Middle', translateTo=spineCurveClusters[2], scale=rigScale * 3, parent=self.bodyCtrl.C, shape='sphere', lockChannels=['r']) # attach controls pm.parentConstraint(chestCtrl.C, pelvisCtrl.C, middleCtrl.Off, sr=['x', 'y', 'z'], mo=1) # attach clusters pm.parent(spineCurveClusters[3:], chestCtrl.C) pm.parent(spineCurveClusters[2], middleCtrl.C) pm.parent(spineCurveClusters[:2], pelvisCtrl.C) # attach chest joint pm.orientConstraint(chestCtrl.C, spineJoints[-1], mo=1) # -2 pm.hide(spineIk) pm.parent(spineIk, self.rigmodule.partsNoTransGrp) # setup IK twist pm.setAttr(spineIk + '.dTwistControlEnable', 1) pm.setAttr(spineIk + '.dWorldUpType', 4) pm.connectAttr(chestCtrl.C + '.worldMatrix[0]', spineIk + '.dWorldUpMatrixEnd') pm.connectAttr(pelvisCtrl.C + '.worldMatrix[0]', spineIk + '.dWorldUpMatrix') # attach root joint pm.parentConstraint(pelvisCtrl.C, rootJnt, mo=1) # clean locators pm.delete(bodyLocator, chestLocator, pelvisLocator)
def ar_addWireTool(curve, mesh, orientSample=None): """ @ add wire from curve and add controller on each cv. Args: curve (str): wire curve. mesh (str): geometry. orientSample (str): sub controller orient aim point. Returns: bool. """ # convert parameters into PyNode. curve = pm.PyNode(curve) mesh = pm.PyNode(mesh) curveUpperGroup = curve.getParent() if not curveUpperGroup: ar_qui.ar_displayMessage( 'error', 'Please create upperGroup on the "%s".' % curve) return False curveShape = curve.getShape() if not curveShape: ar_qui.ar_displayMessage('error', '"%s" has no shape.' % curve) return False # press tab from down line. cvs = pm.ls(curve + '.cv[*]', fl=True) cls = None if not orientSample: cls = pm.cluster(cvs, n=curve + '_Cluster') orientSample = cls[1] # create root group. rootGrp = pm.createNode('transform', n='Wire_' + curve + '_RootGrp', ss=True) controllersGrp = pm.createNode('transform', n=curve + '_Ctrl_Grp', ss=True) jointsGrp = pm.createNode('transform', n=curve + '_Joints_Grp', ss=True) pm.parent(controllersGrp, jointsGrp, rootGrp) pm.select(cl=True) # create main Controller. mainCtrl = curve.duplicate(n=curve + '_MainCtrl')[0] mainCtrl.v.unlock() mainCtrl.v.set(1) # hide default curve. curve.v.unlock() curve.v.set(0) curve.v.lock() pm.parent(mainCtrl, w=True) mainCtrlExtraGrp = pm.createNode('transform', n=curve + '_MainCtrl_ExtraGrp') mainCtrlOffsetGrp = pm.createNode('transform', n=curve + '_MainCtrl_OffsetGrp') pm.parent(mainCtrlExtraGrp, mainCtrlOffsetGrp) pm.delete(pm.parentConstraint(curveUpperGroup, mainCtrlOffsetGrp)) pm.parent(mainCtrl, mainCtrlExtraGrp) # assign pivot and freeze transform main curve. pivPos = pm.xform(mainCtrlExtraGrp, q=True, ws=True, piv=True)[:3] pm.xform(mainCtrl, ws=True, piv=pivPos) pm.makeIdentity(mainCtrl, apply=True, t=1, r=1, s=1, n=0, pn=1) mainCtrl.setAttr('v', l=True, cb=False, k=False) # visibility attributes. pm.addAttr(mainCtrl, longName='visAttrs', at='enum', en='=====', k=True) mainCtrl.visAttrs.lock() pm.addAttr(mainCtrl, ln='clusterVis', at='bool', k=True) pm.addAttr(mainCtrl, ln='jointsVis', at='bool', k=True) pm.addAttr(mainCtrl, ln='subCtrlVis', at='bool', k=True, dv=True) # wire attributes. pm.addAttr(mainCtrl, ln='wireAttrs', at='enum', en='=====', k=True) mainCtrl.wireAttrs.lock() pm.addAttr(mainCtrl, ln='envelope', at='double', min=0, max=1, dv=1, k=True) pm.addAttr(mainCtrl, ln='dropoffDistance', at='double', min=0, dv=1, k=True) # ----------------------- # create joints on each cv. joints = [] for i, cv in enumerate(cvs): pm.select(cl=True) pos = pm.xform(cv, q=True, ws=True, t=True) jnt = pm.joint(p=pos, n=curve + '_' + str(i) + '_jt') joints.append(jnt) mainCtrl.jointsVis.connect(jnt.v) # x axis orient in center and create cluster and parent. for i in range(len(joints)): if i != len(cvs) - 1: pm.delete( pm.aimConstraint(orientSample, joints[i], o=[0, 0, 0], w=True, aim=[1, 0, 0], u=[0, 0, 1], wut="object", wuo=joints[i + 1])) else: pm.delete( pm.aimConstraint(orientSample, joints[i], o=[0, 0, 0], w=True, aim=[1, 0, 0], u=[0, 0, 1], wut="object", wuo=joints[0])) pm.makeIdentity(joints[i], a=True, t=1, r=1, s=1, n=0, pn=1) cvCls = pm.cluster(cvs[i], en=1, n=joints[i][:-2] + 'Cls') pm.parent(cvCls[1], joints[i]) mainCtrl.clusterVis.connect(cvCls[1].v, f=True) if cls: pm.delete(cls) # create controllers. for i in range(len(joints)): # create sub controller. controller = pm.modeling.curve(d=1, p=[[-0.5, 0.5, 0.5], [0.5, 0.5, 0.5], [0.5, -0.5, 0.5], [-0.5, -0.5, 0.5], [-0.5, -0.5, -0.5], [-0.5, 0.5, -0.5], [0.5, 0.5, -0.5], [0.5, -0.5, -0.5], [0.5, -0.5, 0.5], [0.5, 0.5, 0.5], [0.5, 0.5, -0.5], [0.5, -0.5, -0.5], [-0.5, -0.5, -0.5], [-0.5, -0.5, 0.5], [-0.5, 0.5, 0.5], [-0.5, 0.5, -0.5]], k=[ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ], n=joints[i] + '_CTRL') extraGroup = pm.createNode('transform', n=joints[i] + '_CTRL_ExtraGrp', ss=True) offsetGroup = pm.createNode('transform', n=joints[i] + '_CTRL_OffsetGrp', ss=True) # lock and hide unwanted attributes. mainCtrl.subCtrlVis.connect(offsetGroup.v) # controller.r.lock() controller.setAttr('rx', l=True, cb=False, k=False) controller.setAttr('ry', l=True, cb=False, k=False) controller.setAttr('rz', l=True, cb=False, k=False) controller.setAttr('sx', l=True, cb=False, k=False) controller.setAttr('sy', l=True, cb=False, k=False) controller.setAttr('sz', l=True, cb=False, k=False) controller.setAttr('v', l=True, cb=False, k=False) pm.parent(controller, extraGroup) pm.parent(extraGroup, offsetGroup) pm.delete(pm.parentConstraint(joints[i], offsetGroup)) pm.parent(offsetGroup, mainCtrl) pm.parentConstraint(controller, joints[i]) # parent all joints in joints grp. pm.parent(joints, jointsGrp) pm.parent(mainCtrlOffsetGrp, controllersGrp) # add Wire Tool on mesh. wireDeformer = pm.wire(mesh, gw=False, en=1.0, ce=0.0, li=0.0, w=curve, n='wire_' + curve) # connect wire attributes on main controller. mainCtrl.envelope.connect(wireDeformer[0].envelope, f=True) mainCtrl.dropoffDistance.connect(wireDeformer[0].dropoffDistance[0], f=True) ar_qui.ar_displayMessage('success', 'wire tool added successfully.') return True
def doRig(self): nurbsSurf = pm.nurbsPlane(p=(0, 0, 0), ax=(0, 1, 0), w=self.width, lr=0.1, d=3, u=self.div, v=1, ch=0, n=self.flexName + 'FlexNurbsSrf')[0] nurbsSurf.visibility.set(False) nurbsSurf.translate.set(self.width / 2, 0, 0) spacing = 1.0 / float(self.div) start = spacing / 2.0 grp1 = pm.group(n=self.flexName + 'Folicules_grp', empty=True) grp2 = pm.group(em=True, n=self.flexName + 'ribbonGlobalMove') grp3 = pm.group(em=True, n=self.flexName + 'FlexNoMove') for i in range(int(self.div)): foll = self.createFoll(self.flexName + 'Follicle' + str('%02d' % i), nurbsSurf, start + spacing * i, 0.5) jnt1 = pm.joint(p=(0, 0, 0), n=self.flexName + str('%02d' % i) + '_jnt') pm.move(0, 0, 0, jnt1, ls=True) pm.parent(foll, grp1) nurbsSurfBlend = pm.nurbsPlane(p=(0, 0, 0), ax=(0, 1, 0), w=self.width, lr=0.1, d=3, u=self.div, v=1, ch=0, n=self.flexName + 'FlexBlendNurbsSrf')[0] nurbsSurfBlend.translate.set(self.width / 2, 0, 0) pm.blendShape(nurbsSurfBlend, nurbsSurf, frontOfChain=True, tc=0, w=(0, 1)) crv = pm.curve(d=2, p=[((self.width * -0.5), 0, 0), (0, 0, 0), ((self.width * 0.5), 0, 0)], k=[0, 0, 1, 1], n=self.flexName + 'Crv') crv.translate.set(self.width / 2, 0, 0) cls1 = pm.cluster(crv + '.cv[0]', crv + '.cv[1]', rel=True, n=self.flexName + 'Cls1') pm.move((self.width * -0.5), 0, 0, cls1[1] + '.scalePivot', cls1[1] + '.rotatePivot') cls2 = pm.cluster(crv + '.cv[2]', crv + '.cv[1]', rel=True, n=self.flexName + 'Cls2') pm.move((self.width * 0.5), 0, 0, cls2[1] + '.scalePivot', cls2[1] + '.rotatePivot') cls3 = pm.cluster(crv + '.cv[1]', rel=True, n=self.flexName + 'Cls3') pm.percent(cls1[0], crv + '.cv[1]', v=0.5) pm.percent(cls2[0], crv + '.cv[1]', v=0.5) twist = pm.nonLinear(nurbsSurfBlend, type='twist', n=self.flexName + 'Twist') twist[1].rotate.set(0, 0, 90) wir = pm.wire(nurbsSurfBlend, gw=False, en=1.000000, ce=0.000000, li=0.000000, w=crv, dds=(0, 20)) wireNode = pm.PyNode(wir[0]) baseWire = [x for x in wireNode.connections() if 'BaseWire' in x.name()] cntrl1 = controlTools.cntrlCrv(name=self.flexName + 'aux1', icone='grp') cntrl2 = controlTools.cntrlCrv(name=self.flexName + 'aux2', icone='grp') cntrl3 = controlTools.cntrlCrv(name=self.flexName + 'aux3', icone='grp') pos = pm.pointOnSurface(nurbsSurfBlend, u=0.0, v=0.5) cntrl1.getParent().translate.set(pos) pos = pm.pointOnSurface(nurbsSurfBlend, u=1.0, v=0.5) cntrl2.getParent().translate.set(pos) pos = pm.pointOnSurface(nurbsSurfBlend, u=0.5, v=0.5) cntrl3.getParent().translate.set(pos) cntrl1.addAttr('twist', at='float', dv=0, k=1) cntrl2.addAttr('twist', at='float', dv=0, k=1) pm.pointConstraint(cntrl1, cntrl2, cntrl3.getParent()) cntrl1.translate >> cls1[1].translate cntrl2.translate >> cls2[1].translate cntrl3.translate >> cls3[1].translate cntrl2.twist >> twist[0].startAngle cntrl1.twist >> twist[0].endAngle pm.parent(nurbsSurf, cntrl1.getParent(), cntrl2.getParent(), cntrl3.getParent(), grp2) pm.parent(grp1, nurbsSurfBlend, cls1[1], cls2[1], cls3[1], baseWire, crv, twist[1], grp3) pm.setAttr(grp3 + '.visibility', 0) # pm.group (grp1,grp2,grp3,n=self.flexName+'Flex_grp') # implementar squash/stretch # implementar o connect to limb
def __ikJj(self): self.ikJj = [] #create IKRibbonSpine #ribbon spine info: curveInfo = [0,(self.segment - 1) / 4,(self.segment - 1) / 2, ((self.segment - 1) / 2 + (self.segment - 1)) / 2, (self.segment - 1)] ribbonCurve = [] self.folList = [] #create curve for jjInfo in curveInfo: ribonJjPos = self.spineFkBlendChain.chain[jjInfo].getTranslation(space = 'world') ribbonCurve.append(ribonJjPos) #set ribbon offset offset = float(self.length * 0.05) #set ribbon cur ribbonCurveL = pm.curve(d = 3,p = [ribbonCurve[0],ribbonCurve[1],ribbonCurve[2],ribbonCurve[3],ribbonCurve[4]], k = [0,0,0,1,2,2,2],n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbonL','gud')) pm.move(offset,0,0,ribbonCurveL) ribbonCurveR = pm.curve(d = 3,p = [ribbonCurve[0],ribbonCurve[1],ribbonCurve[2],ribbonCurve[3],ribbonCurve[4]], k = [0,0,0,1,2,2,2],n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbonR','gud')) pm.move(-offset,0,0,ribbonCurveR) ribbonCurveR.setParent(self.guideGrp) ribbonCurveL.setParent(self.guideGrp) #create ribbon surf ribbonGeo = pm.loft(ribbonCurveR,ribbonCurveL,ch = 0,u = 1,c = 0,ar = 1,d = 3,ss = 1, rn = 0,po = 0,rsn = 1, n = nameUtils.getUniqueName(self.side,self.baseName + '_ribbon','surf')) ribbonClusList = [] self.ribbonJc = [] self.spineCc = [] #get loc pos for num,loc in enumerate(self.fkGuides): startLoc = self.fkGuides[0] midLoc = self.fkGuides[(len(self.fkGuides) - 1) / 2] endLoc = self.fkGuides[-1] startLocPos = pm.xform(startLoc,ws = 1,t = 1,q = 1)[1] midLocPos = pm.xform(midLoc,ws = 1,t = 1,q = 1)[1] endLocPos = pm.xform(endLoc,ws = 1,t = 1,q = 1)[1] #get Jc pos for num in [0,2,4]: pos = pm.select(ribbonGeo[0] + '.cv[' + str(num) + '][0:3]',r = 1) clus = pm.cluster() pm.rename(clus[1],nameUtils.getUniqueName(self.side,self.baseName + '_ribbon','cls')) ribbonClusList.append(clus) pm.select(cl = 1) #set cvpos for vert in [1,3]: for row in range(0,4): cvNum = pm.select(ribbonGeo[0] + '.cv[' + str(vert) + '][' + str(row) + ']',r = 1) oriPos = pm.xform(cvNum,ws = 1,t = 1,q = 1) if vert == 1: pm.xform(cvNum,ws = 1,t = (oriPos[0],(startLocPos + midLocPos) / 2,oriPos[2])) elif vert == 3: pm.xform(cvNum,ws = 1,t = (oriPos[0],(endLocPos + midLocPos) / 2,oriPos[2])) #set Jc and Jc ctrl for num,x in enumerate(ribbonClusList): jc = pm.joint(p = x[1].getRotatePivot(), n = nameUtils.getUniqueName(self.side,self.baseName + self.nameList[num],'jc'), radius = self.length / 3) self.ribbonJc.append(jc) pm.select(cl = 1) pm.delete(ribbonClusList[num]) pm.select(cl = 1) cc = control.Control(self.side,self.baseName + self.nameList[num],size = self.ikSize,aimAxis = self.ctrlAxis) cc.circleCtrl() pm.makeIdentity(cc.control,apply = True,t=0,r=1,s=0,n=0,pn=1) # self.bodyCtrl.control.ik_vis.connect(cc.controlGrp.v) self.bodyCtrl.control.ik_vis.connect(cc.control.getShape().v) self.spineCc.append(cc.control) control.lockAndHideAttr(cc.control,['sx','sy','sz','v']) pm.xform(cc.controlGrp,ws = 1,matrix = jc.worldMatrix.get()) #skin Jc for num,jc in enumerate(self.ribbonJc): jc.setParent(self.spineCc[num]) ribbonSkin = pm.skinCluster(self.ribbonJc[0],self.ribbonJc[1],self.ribbonJc[2],ribbonGeo[0], tsb = 1,ih = 1,mi = 3,dr = 4,rui = 1,n = nameUtils.getSkinName()) #skin pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[0][0:3]', transformValue=[(self.ribbonJc[0],1)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[1][0:3]', transformValue=[(self.ribbonJc[1],0.5),(self.ribbonJc[0],0.5)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[2][0:3]', transformValue=[(self.ribbonJc[1],1)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[3][0:3]', transformValue=[(self.ribbonJc[1],0.5),(self.ribbonJc[2],0.5)]) pm.skinPercent(ribbonSkin,ribbonGeo[0] + '.cv[4][0:3]', transformValue=[(self.ribbonJc[2],1)]) #set fol #create / rename fol self.folGrp = pm.group(em = 1,n = nameUtils.getUniqueName(self.side,self.baseName + 'Fol','grp')) for fol in range(0,self.segment): #createNodeName follicleTransName = nameUtils.getUniqueName(self.side,self.baseName,'fol') follicleShapeName = nameUtils.getUniqueName(self.side,self.baseName,'folShape') #createNode follicleShape = pm.createNode('follicle',n = follicleShapeName) follicleTrans = pm.listRelatives(follicleShape, parent=True)[0] follicleTrans = pm.rename(follicleTrans, follicleTransName) # connect the surface to the follicle if ribbonGeo[0].getShape().nodeType() == 'nurbsSurface': pm.connectAttr((ribbonGeo[0] + '.local'), (follicleShape + '.inputSurface')) #Connect the worldMatrix of the surface into the follicleShape pm.connectAttr((ribbonGeo[0].getShape() + '.worldMatrix[0]'), (follicleShape + '.inputWorldMatrix')) #Connect the follicleShape to it's transform pm.connectAttr((follicleShape + '.outRotate'), (follicleTrans + '.rotate')) pm.connectAttr((follicleShape + '.outTranslate'), (follicleTrans + '.translate')) #Set the uValue and vValue for the current follicle pm.setAttr((follicleShape + '.parameterV'), 0.5) pm.setAttr((follicleShape + '.parameterU'), float(1.0 / float(self.segment - 1)) * fol) #Lock the translate/rotate of the follicle pm.setAttr((follicleTrans + '.translate'), lock=True) pm.setAttr((follicleTrans + '.rotate'), lock=True) pm.setAttr((follicleShape + '.degree'),1) #parent self.folList.append(follicleTrans) follicleTrans.setParent(self.folGrp) #rebuild fol pos self.spineIkBlendJoint = [] self.stretchCube = [] for num,fol in enumerate(self.folList): jj = pm.joint(p = (0,0,0),n = nameUtils.getUniqueName(self.side,self.baseName,'jj'), radius = self.length / 5) self.spineIkBlendJoint.append(jj) jj.setParent(fol) tempCube = pm.polyCube(ch = 1,o = 1,w = float(self.length / 5),h = float(self.length / 10), d = float(self.length / 5),cuv = 4,n = nameUtils.getUniqueName(self.side,self.baseName,'cube')) tempCube[0].setParent(jj) tempCube[0].v.set(0) self.stretchCube.append(tempCube[0]) jj.translateX.set(0) jj.translateY.set(0) jj.translateZ.set(0) self.ikJj.append(jj) #create spine grp self.spineIkGrp = pm.group(self.spineCc[0].getParent(),self.spineCc[1].getParent(),self.spineCc[2].getParent(),self.folGrp,ribbonGeo[0], n = nameUtils.getUniqueName(self.side,self.baseName + 'Ik','grp')) ribbonGeo[0].inheritsTransform.set(0) self.folGrp.inheritsTransform.set(0) #clean self.spineIkGrp.setParent(self.bodyCtrl.control) #temp self.spineIkGrp.v.set(1) '''put chest ctrl under chest cc''' '''put leg under hip cc'''
ikStartJ = pm.duplicate(startJ, name = 'ikJoint_Weapon2', renameChildren = True)[0] counter = 18 for i in pm.listRelatives(ikStartJ, ad = True): pm.rename(i, 'ikJoint_Weapon' + str(counter)) counter -= 1 ik_return = pm.ikHandle(name = 'whip_IK', startJoint = ikStartJ, endEffector = ikEndJ, solver = 'ikSplineSolver', ns = 4) #[0] is the ikHandle itself, [1] is the effector and [2] is the spline curve that is created pm.rebuildCurve(ik_return[2], constructionHistory = True, rpo = True, rt = 0, end =1, kr = 0, kep = True, kt = 0, spans = numOfContr, degree = 3, tolerance = 0.01) #rebuilding curve to desired parameters masterContr = pm.circle(name = 'whipContr_Master', radius = 12.5)#master controller pm.addAttr(masterContr, longName = 'IK', attributeType = 'bool', defaultValue = 0) curveCVs = pm.ls(ik_return[2] + '.cv[0:]', fl = True) whipGroup = pm.group(name = 'whipGroup') for i, cv in enumerate(curveCVs): #building clusters on each curve print i, cv clust = pm.cluster(cv, name = 'whipCluster' + str(i)) circ = pm.circle(name = 'whipContr_' + str(i), radius = 8) pm.xform(circ, translation = pm.xform(curveCVs[i], query = True, translation = True, ws = True), rotation = [0, 0, 0], ws = True) #moving the circle to where the cluster is pm.makeIdentity(circ, apply = True, t = 1, r = 1, s = 1, n = 0) pm.parentConstraint(circ, clust, mo = True) pm.parent(circ[0], clust[1], whipGroup) pm.circle(name = 'whipContr_Master', radius = 12.5) #else: # pm.confirmDialog(title = '鞭リッグツール', message = 'シーンに鞭が見つけていません', button = ['OK'])
def __init__(self, neckJoints, headJnt, # neckCurve, prefix='neck', rigScale=1.0, baseRig=None ): """ :param neckJoints: list( str ), list of neck joints :param headJnt: str, head joint at the end of neck joint chain :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: instance of base.module.Base class :return: dictionary with rig module objects """ # :param neckCurve: str, name of neck cubic curve with 5 CVs matching neck joints # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # make IK handle neckIk, effector, neckCurve = pm.ikHandle(n=prefix + '_IKH', sol='ikSplineSolver', sj=neckJoints[0], ee=neckJoints[-1], createCurve=True, numSpans=2) # rename curve pm.rename(neckCurve, prefix + '_CRV') # make neck curve clusters neckCurveCVs = pm.ls(neckCurve + '.cv[*]', fl=1) numNeckCVs = len(neckCurveCVs) neckCurveClusters = [] for i in range(numNeckCVs): cls = pm.cluster(neckCurveCVs[i], n=prefix + 'Cluster%d' % (i + 1))[1] neckCurveClusters.append(cls) pm.hide(neckCurveClusters) # parent neck curve pm.parent(neckCurve, self.rigmodule.partsNoTransGrp) # make attach groups self.bodyAttachGrp = pm.group(n=prefix + 'BodyAttach_GRP', em=1, p=self.rigmodule.partsGrp) self.baseAttachGrp = pm.group(n=prefix + 'BaseAttach_GRP', em=1, p=self.rigmodule.partsGrp) pm.delete(pm.pointConstraint(neckJoints[0], self.baseAttachGrp)) # make controls headMainCtrl = control.Control(prefix=prefix + 'HeadMain', translateTo=neckJoints[-1], rotateTo=headJnt, scale=rigScale * 5, parent=self.rigmodule.controlsGrp, shape='head') headLocalCtrl = control.Control(prefix=prefix + 'HeadLocal', translateTo=headJnt, rotateTo=headJnt, scale=rigScale * 4, parent=headMainCtrl.C, shape='circleX', lockChannels=['t']) middleCtrl = control.Control(prefix=prefix + 'Middle', translateTo=neckCurveClusters[2], rotateTo=neckJoints[2], scale=rigScale * 4, parent=self.rigmodule.controlsGrp, shape='circleX', lockChannels=['r']) # attach controls pm.parentConstraint(headMainCtrl.C, self.baseAttachGrp, middleCtrl.Off, sr=['x', 'y', 'z'], mo=1) pm.orientConstraint(self.baseAttachGrp, middleCtrl.Off, mo=1) pm.parentConstraint(self.bodyAttachGrp, headMainCtrl.Off, mo=1) # attach clusters pm.parent(neckCurveClusters[3:], headMainCtrl.C) pm.parent(neckCurveClusters[2], middleCtrl.C) pm.parent(neckCurveClusters[:2], self.baseAttachGrp) # attach joints pm.orientConstraint(headLocalCtrl.C, headJnt, mo=1) pm.hide(neckIk) pm.parent(neckIk, self.rigmodule.partsNoTransGrp) # setup IK twist pm.setAttr(neckIk + '.dTwistControlEnable', 1) pm.setAttr(neckIk + '.dWorldUpType', 4) pm.connectAttr(headMainCtrl.C + '.worldMatrix[0]', neckIk + '.dWorldUpMatrixEnd') pm.connectAttr(self.baseAttachGrp + '.worldMatrix[0]', neckIk + '.dWorldUpMatrix')
def createLatticeControls(): ''' assume lattice is already created and xformed ''' lat = nt.Transform(u'CT_eyeLattice_dfmLattice') # defining lattice points lf_in_col = 5 lf_mid_col = 6 lf_out_col = 7 rt_out_col = 1 rt_mid_col = 2 rt_in_col = 3 up_row = 3 dn_row = 2 deformPoints = { 'LT_eyeUpIn': [lat.pt[lf_in_col][up_row][0], lat.pt[lf_in_col][up_row][1]], 'LT_eyeUpMid': [lat.pt[lf_mid_col][up_row][0], lat.pt[lf_mid_col][up_row][1]], 'LT_eyeUpOut': [lat.pt[lf_out_col][up_row][0], lat.pt[lf_out_col][up_row][1]], 'LT_eyeDnIn': [lat.pt[lf_in_col][dn_row][0], lat.pt[lf_in_col][dn_row][1]], 'LT_eyeDnMid': [lat.pt[lf_mid_col][dn_row][0], lat.pt[lf_mid_col][dn_row][1]], 'LT_eyeDnOut': [lat.pt[lf_out_col][dn_row][0], lat.pt[lf_out_col][dn_row][1]], 'RT_eyeUpIn': [lat.pt[rt_in_col][up_row][0], lat.pt[rt_in_col][up_row][1]], 'RT_eyeUpMid': [lat.pt[rt_mid_col][up_row][0], lat.pt[rt_mid_col][up_row][1]], 'RT_eyeUpOut': [lat.pt[rt_out_col][up_row][0], lat.pt[rt_out_col][up_row][1]], 'RT_eyeDnIn': [lat.pt[rt_in_col][dn_row][0], lat.pt[rt_in_col][dn_row][1]], 'RT_eyeDnMid': [lat.pt[rt_mid_col][dn_row][0], lat.pt[rt_mid_col][dn_row][1]], 'RT_eyeDnOut': [lat.pt[rt_out_col][dn_row][0], lat.pt[rt_out_col][dn_row][1]] } # create clusters clusters = {} dfg = pm.group(em=True, n='CT_eyeLatticeClusters_dfg') for name, components in deformPoints.items(): dfm, hdl = pm.cluster(components[1], n=name + '_cluster_dfm', relative=True) # above: use relative - the cluster handles will be parented with the face/head control # so parentConstraint will only drive offset values to the handles # so we'll make sure to only use the local offset values dfm.setGeometry(components[0]) dfg | hdl clusters[name] = dfm, hdl # create controls controlZOffset = 0 childEyeShapers = [] localReadersGrp = pm.group(em=True, n='CT_eyeLatticeClusters_localReadersGrp') for name, (dfm, hdl) in clusters.items(): pt = hdl.getRotatePivot(space='world') pt = dt.Point(pt + (0, 0, controlZOffset)) ctl = pm.circle(n=name + '_eyeShaper_ctl') ctg = pm.group(ctl, n=name + '_eyeShaper_ctg') cth = pm.group(ctg, n=name + '_eyeShaper_cth') cth.setTranslation(pt) # shape ctl ctl[1].radius.set(0.5) ctl[1].sweep.set(359) ctl[1].centerZ.set(0) pm.delete(ctl, ch=True) # scale transform ctl[0].sy.set(0.333) pm.makeIdentity(ctl[0], s=True, a=True) # color shape if 'LT_' in name: controls.setColor(ctl[0], 18) elif 'RT_' in name: controls.setColor(ctl[0], 20) else: pm.warning('unknown side %s' % name) # parent constraint cluster (using matrices) reader = localReader.create(hdl, localReadersGrp) pm.parentConstraint(ctl[0], reader, mo=True) childEyeShapers.append(cth) # control parents parentEyeShapers = [] for parentCtlName in ('RT_eyeUp', 'RT_eyeDn', 'LT_eyeUp', 'LT_eyeDn'): # create parent control at cluster location clusHdl = clusters[parentCtlName + 'Mid'][1] pt = clusHdl.getRotatePivot(space='world') pt = pt + (0, 0, controlZOffset) ctl = pm.circle(n=parentCtlName + '_eyeShaper_ctl') ctg = pm.group(ctl, n=parentCtlName + '_eyeShaper_ctg') cth = pm.group(ctg, n=parentCtlName + '_eyeShaper_cth') cth.setTranslation(pt) # shape ctl ctl[1].radius.set(2.5) ctl[1].sweep.set(359) ctl[1].centerZ.set(0) pm.delete(ctl, ch=True) # scale transform ctl[0].sy.set(0.1) pm.makeIdentity(ctl[0], s=True, a=True) # color shape if 'LT_' in parentCtlName: controls.setColor(ctl[0], 18) elif 'RT_' in parentCtlName: controls.setColor(ctl[0], 20) else: pm.warning('unknown side %s' % name) # parent other controls children = [n for n in childEyeShapers if parentCtlName in n.name()] pm.parent(children, ctl[0]) parentEyeShapers.append(cth) # group both controls and clusters under the CTG, # so cluster will only use local offsets eyeShaperCtg = pm.group(parentEyeShapers, localReadersGrp, n='CT_eyeLatticeControls_ctg') return eyeShaperCtg
def create(ctl, tipGeo, weights, name, keys, addGeos=[], useScale=False): ''' tipGeo - vtx of the tip of the eye weights - list of weights for each loop radiating outwards (including geoTip) e.g. [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1] addGeo - list of additional geometry for cluster to deform name - 'pupil' or 'iris' e.g.: geo = nt.Mesh(u'LT_eyeball_geoShape') tipGeo = geo.vtx[381] ctl = nt.Transform(u'LT_eye_ctl') name = '_iris' keys = {'sx': {0.01:0.01, 1:1, 2:2}, 'sy': {0.01:0.01, 1:1, 2:2}, 'sz': {0.01:0.01, 1:1, 2:3.75}} weights = [1, 1, 1, 1, 1, .95, 0.75, 0.5, .25, .1] ''' geo = tipGeo.node() dfm, hdl = pm.cluster(tipGeo, n=ctl + name + '_dfm', foc=True) dfg = pm.group(hdl, n=ctl + name + '_dfg') rp = hdl.getRotatePivot(space='world') sp = hdl.getScalePivot(space='world') dfg.setRotatePivot(rp, space='world') dfg.setScalePivot(sp, space='world') dfh = pm.group(dfg, n=ctl + name + '_dfh') ctl.addAttr(name, min=0.01, max=2, dv=1, k=True) for attr, key in keys.items(): rt.connectSDK(ctl.attr(name), hdl.attr(attr), key) loopNums = len(weights) - 1 vertLoops = mesh.VertexLoops([tipGeo], loopNums) # add membership pm.select(vertLoops[:]) for vertLoop in vertLoops[:]: for eachVert in vertLoop: dfm.setGeometry(eachVert) for loopId, weight in enumerate(weights): for eachVert in vertLoops[loopId]: print eachVert dfm.setWeight(geo, 0, eachVert, weight) # add additional geometries for eachGeo in addGeos: dfm.setGeometry(eachGeo, foc=True) if useScale: # modulate cluster scale by control scale for eachAttr in ('sx', 'sy', 'sz'): scaleInput = hdl.attr(eachAttr).inputs(p=True)[0] mdl = pm.createNode('multDoubleLinear', n=hdl + '_' + eachAttr + '_scale_mdl') scaleInput >> mdl.input1 ctl.attr(eachAttr) >> mdl.input2 mdl.output >> hdl.attr(eachAttr) return dfh
def cluster(cls, name=''): node = pm.cluster() cls.rename(node, name) return node[1]
def rigHeadCmd( prefix='head_', suffix='', hasStretch=True ): exp_template = EXP_HEAD labels = { 'control' : prefix + 'control' + suffix, 'aimControl' : prefix + 'aim' + suffix, 'ik' : prefix + 'ik' + suffix, 'ikEnd' : prefix + 'ik_end' + suffix, 'parent' : prefix + 'parent' + suffix, 'expression' : prefix + 'control' + suffix + '_EXP', 'parent' : prefix + 'parent' + suffix, 'pivot' : prefix + 'pivot' + suffix, } try: start_joint = pm.ls(sl=1,type="joint")[0] except ValueError: raise ValueError, "Select the root joint to setup." end_joint = start_joint.getChildren(type='joint')[0] neck_joint = start_joint.getParent() parent_joint = neck_joint.getParent() if neck_joint is None: raise ValueError, "Start joint must have a parent joint (neck)." if parent_joint is None: raise ValueError, "Start joint parent must have a parent transform (spine)." unit_scale = start_joint.getRotatePivot(ws=1)[-1] start_point = start_joint.getRotatePivot(ws=1) * unit_scale end_point = end_joint.getRotatePivot(ws=1) * unit_scale mid_point = ( start_point + end_point ) / 2 length = start_point.distanceTo( end_point ) aim_point = Vector( start_point[0], start_point[1], start_point[1])*100 # -- build controls control = createNurbsShape( labels['control'], width=length, height=length*1.2, depth=length*1.1 ) control.translate.set( mid_point ) pm.makeIdentity( control, apply=True, t=1 ) control.rotatePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.scalePivot.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.selectHandle.set( start_joint.getRotatePivot(ws=1) * unit_scale ) control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) control.addAttr( "aimBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- build aim control aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/1.5 ) aim_control.translate.set( aim_point ) pm.makeIdentity( aim_control, apply=True, t=1 ) pm.aimConstraint( start_joint, aim_control, weight=1, aimVector=(0, 0, 1) ) # -- Create Aim Line aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] ) line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 ) line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 ) pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 ) pm.pointConstraint( start_joint, line_handle1, offset=(0,0,0), weight=1 ) line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" ) line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" ) pm.parent( [aim_line, line_group0, line_group1, aim_control] ) line_group0.v.set(0) line_group1.v.set(0) setAttrs( line_group0, ['t','r','s','v'], lock=1 ) setAttrs( line_group1, ['t','r','s','v'], lock=1 ) setAttrs( aim_line, ['t','r','s','v'], lock=1 ) aim_line.overrideEnabled.set(1) aim_line.overrideDisplayType.set(1) # -- build helper groups pivot_grp = pm.group( n=labels['pivot'], em=1 ) parent_grp = pm.group( pivot_grp, n=labels['parent'] ) parent_grp.translate.set( control.getRotatePivot(ws=1) * unit_scale ) pm.makeIdentity( parent_grp, apply=True, t=1 ) pivot_grp.rotateOrder.set(2) # -- create ik handles main_ik, main_ee = pm.ikHandle( n=labels['ik'], sj=neck_joint, ee=end_joint, sol='ikRPsolver', dh=1 ) #main_ik, main_ee = pm.ikHandle( n=labels['ik'], sj=neck_joint, ee=start_joint, sol='ikRPsolver', dh=1 ) #end_ik, end_ee = pm.ikHandle( n=labels['ikEnd'], sj=start_joint, ee=end_joint, sol='ikSCsolver', dh=1 ) pm.parent( main_ik, control ) pm.parent( control, pivot_grp ) # -- set up constraints #pm.aimConstraint( control, aim_control, weight=1, aimVector=(0, 0, -1), mo=1 ) pm.aimConstraint( aim_control, pivot_grp, weight=1, aimVector=(0, 0, 1), mo=1 ) pm.setKeyframe( pivot_grp.r ) pm.parentConstraint( parent_joint, parent_grp, weight=1, mo=1 ) resetIkSetupCmd(start_joint, control) resetIkSetupCmd(start_joint, aim_control) exp_str = exp_template \ % { 'control' : control, 'start_joint' : start_joint, 'end_joint' : end_joint, 'parent_joint' : parent_joint, 'main_ik' : main_ik, #'end_ik' : end_ik, 'pivot' : pivot_grp, 'shape' : control.getShape(), } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) # -- make things look pretty for n in pm.ls( [main_ik], dag=1, type="transform" ): n.visibility.set(0) control.displayHandle.set(1) addToSet( [control, aim_control], 'controlsSet' ) setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(aim_control.v, keyable=0 ) pm.select( [control,aim_control], r=1 ) pm.color( ud=CntlColors.head ) return [ control, aim_control ]
def createCustom(self, _HiRez=pm.selected(), _LoRez=pm.selected()): """ Custom wrapDeformer Select target - HiRez first, then the source - LoRez @param Hirez: Target which will receive the wrap : str or selection @param Lorez: Source : str of selection ## EXTERIOR CLASS BUILD #------------------------ import adb_utils.Script__WrapDeformer as adbWrap reload(adbWrap) #or from adb_utils.Script__WrapDeformer import wrapDeformer """ ## Define Variable type if isinstance(_HiRez, str) and isinstance(_LoRez, str): # print('a') HiRez = _HiRez LoRez = _LoRez elif len(_HiRez) == 2: # print('b') HiRez = _HiRez[0] LoRez = _LoRez[1] else: # print('c') HiRez = _HiRez LoRez = _LoRez ## get Orig node orig_node = self.shapeOrig(LoRez) if orig_node is None: cls = pm.cluster(LoRez) pm.delete(cls) orig_node = self.shapeOrig(LoRez) # raise RuntimeError("No 'Orig' Node for: {}".format(LoRez)) ## Wrap Node creation pm.select(HiRez, r=True) pm.select(LoRez, add=True) wrapData = pm.deformer(HiRez, name='{}_{}'.format(HiRez, 'wrap'), type='wrap')[0] pm.PyNode(wrapData).maxDistance.set(1) pm.PyNode(wrapData).autoWeightThreshold.set(1) pm.PyNode(wrapData).exclusiveBind.set(0) pm.PyNode(wrapData).falloffMode.set(0) ## add custom attribute on LoRez mesh if adb.attrExist(LoRez, 'dropoff'): pass else: LoRez_node = adbAttr.NodeAttr([LoRez]) LoRez_node.addAttr('dropoff', 4) LoRez_node.addAttr('smoothness', 0) LoRez_node.addAttr('inflType', 2) ## Connections (pm.PyNode(LoRez).getShape() ).worldMesh[0] >> pm.PyNode(wrapData).driverPoints[0] (pm.PyNode(HiRez).getShape() ).worldMatrix[0] >> pm.PyNode(wrapData).geomMatrix pm.PyNode(LoRez).dropoff >> pm.PyNode(wrapData).dropoff[0] pm.PyNode(LoRez).inflType >> pm.PyNode(wrapData).inflType[0] pm.PyNode(LoRez).smoothness >> pm.PyNode(wrapData).smoothness[0] pm.PyNode(orig_node).worldMesh[0] >> pm.PyNode(wrapData).basePoints[0] ## Clean Up) pm.PyNode(LoRez).v.set(0) sys.stdout.write('custom wrap deformer created \n') self.wrapNode = None self.wrapNode = wrapData return self.wrapNode
def createIKspline(IK_chain = None, ikSpineGrp = None): """ maj: x-- add pelvis control -- add follow on mid ctrl debug: -- orient ik mid ctrl in the same orientation then other controllers """ # insert joints # global IKjointList, dwCtrl,upCtrl IKjointList = [] jointIt = 3 for jnt in IK_chain: IKjointList.append(jnt) child = jnt.getChildren() if len(child)>0: num = jointIt rad = pm.joint(jnt, query = True , radius = True)[0] dist = pm.joint(child[0], query = True , relative = True, position = True)[0] gap = dist/(num) for i in range((num-1),0,-1): newJnt = pm.insertJoint(jnt) pm.joint( newJnt, edit = True,component = True, relative = True, radius = rad, position = ((gap*i),0,0)) IKjointList.append(newJnt) # create ikhandle IKspine = pm.ikHandle(solver = "ikSplineSolver", name = "IKspine", simplifyCurve = True, startJoint = IK_chain[0], endEffector = IK_chain[(len(IK_chain)-1)], createCurve = True, numSpans = 4) IKhandle = IKspine[0] IKcurve = IKspine[2] IKhandle.setParent(ikSpineGrp) curveJointList = pm.ikHandle(IKhandle, query = True, jointList = True) # create clusters on point cvsList = (IKcurve.getShape()).getCVs() clusterGrp = pm.group(name = "cluster_grp", empty = True) clusterGrp.setParent(ikSpineGrp) ctrlGrp = pm.group(name = "IK_ctrls_grp", empty = True) ctrlGrp.setParent(ikSpineGrp) # parent cluster to sphere ctrlList = [] clusterList = [] for i,cv in enumerate(cvsList): cluster = pm.cluster("curve1.cv[%s]" % i) cluster[0].setAttr("relative", 1) tmpCluster = cluster[1] tmpCluster.setParent(clusterGrp) clusterList.append(tmpCluster) oneCtrl = helpers.createNurbsSphere(rad = 0.5) ctrlList.append(oneCtrl) # oneCtrl.setParent(ctrlGrp) tmpPoint = pm.pointConstraint(tmpCluster, oneCtrl) pm.delete(tmpPoint) pm.pointConstraint(oneCtrl, tmpCluster) for c in ctrlList: c.setParent(ctrlGrp) ctrlListGrp = helpers.insertGroups(ctrlList) # create main ctrls # orient up and down ctrls as joint selection upCtrlGrp, upCtrl = helpers.createOneCircle([1,0,0], sel = sel[0], rad = 4, suf= "_IK_ctrl") dwCtrlGrp, dwCtrl = helpers.createOneCircle([1,0,0], sel = sel[len(sel)-1], rad = 4, suf= "_IK_ctrl") idMid = int((pm.datatypes.round(float(len(ctrlListGrp))/2)) - 1) midCtrlGrp, midCtrl = helpers.createOneCircle([0,1,0], sel = ctrlList[idMid], rad = 4, suf= "_IK_ctrl") upCtrlGrp.setParent(ctrlGrp) dwCtrlGrp.setParent(ctrlGrp) midCtrlGrp.setParent(ctrlGrp) upLoc = helpers.createOneLoc(parentToWorld = False, s = upCtrl) dwLoc = helpers.createOneLoc(parentToWorld = False, s = dwCtrl) upLoc.setAttr("tz", 2) dwLoc.setAttr("tz", 2) # parent sphere ctrls to main ctrls ctrlListGrp[0].setParent(upCtrl) ctrlListGrp[1].setParent(upCtrl) ctrlListGrp[idMid - 1].setParent(midCtrl) ctrlListGrp[idMid].setParent(midCtrl) ctrlListGrp[idMid + 1].setParent(midCtrl) ctrlListGrp[(len(ctrlListGrp)-2)].setParent(dwCtrl) ctrlListGrp[(len(ctrlListGrp)-1)].setParent(dwCtrl) # add twist IKhandle.setAttr("dTwistControlEnable", 1) IKhandle.setAttr("dWorldUpType", 2) IKhandle.setAttr("dWorldUpAxis", 3) pm.connectAttr(upLoc.worldMatrix, IKhandle.dWorldUpMatrix, force = True) pm.connectAttr(dwLoc.worldMatrix, IKhandle.dWorldUpMatrixEnd, force = True) #### add stretch # add parameters on upper control pm.addAttr(dwCtrl, longName = "________", attributeType = "enum", enumName = "CTRLS:") pm.setAttr(dwCtrl.________, keyable = True, lock = True) # make stretch editable pm.addAttr(dwCtrl, longName = "stretch", attributeType = "double", min = 0, max = 1, dv = 0) # pm.addAttr(dwCtrl, longName = "squash", attributeType = "double", min = 0, max = 1, dv = 0) pm.addAttr(dwCtrl, longName = "followJoint", attributeType = "double", min = 0, max = 1, dv = 1) pm.addAttr(dwCtrl, longName = "followCtrl", attributeType = "double", min = 0, max = 1, dv = 0) pm.setAttr(dwCtrl.stretch, keyable = True) # pm.setAttr(dwCtrl.squash, keyable = True) pm.setAttr(dwCtrl.followJoint, keyable = True) pm.setAttr(dwCtrl.followCtrl, keyable = True) subFollowNode = pm.createNode('plusMinusAverage', name = "follow_mode_compense") subFollowNode.setAttr("input1D[0]", 1) subFollowNode.setAttr('operation', 2) pm.connectAttr(dwCtrl.followJoint, subFollowNode.input1D[1], f = True) pm.connectAttr(subFollowNode.output1D, dwCtrl.followCtrl, f = True) newJointsNum = (len(IKjointList)) # add arclenght on curve arcLenNode = pm.arclen(IKcurve, ch = True) defaultSize = arcLenNode.getAttr("arcLength") # multiply/divide default size by current size mdNode = pm.createNode("multiplyDivide") mdNode.setAttr("operation", 2 ) mdNode.setAttr("input2X", arcLenNode.getAttr("arcLength") ) pm.connectAttr(arcLenNode.arcLength, mdNode.input1X) # average to calculate stretch addition : stretch - 1 addStretchNode = pm.createNode("plusMinusAverage", name = "add_stretch") addStretchNode.setAttr("operation", 2) pm.connectAttr(mdNode.outputX, addStretchNode.input1D[0]) addStretchNode.setAttr("input1D[1]", 1) # multiplydivide to mutiply stretch addition by strecth parameter stretchMultiplyNode = pm.createNode("multiplyDivide", name = "multiply_stretch") pm.connectAttr(addStretchNode.output1D, stretchMultiplyNode.input1X) pm.connectAttr(dwCtrl.stretch, stretchMultiplyNode.input2X) # average to addition 1 + stretch addition addStretchFinalNode = pm.createNode("plusMinusAverage", name = "add_stretch") addStretchFinalNode.setAttr("operation", 1) pm.connectAttr(stretchMultiplyNode.outputX, addStretchFinalNode.input1D[0]) addStretchFinalNode.setAttr("input1D[1]", 1) for jnt in IKjointList: jntNode = (pm.PyNode(jnt)) try: pm.connectAttr(addStretchFinalNode.output1D, jntNode.scaleX) except: print(Exception) ## add parametrable squash ## follow control on neck lastJoint = IKjointList[-1] IKfollowJnt = pm.duplicate(lastJoint, name = (lastJoint.nodeName() + "_follow"))[0] IKfollowJnt.setAttr("scaleX", 1) IKfollowJnt.setParent(ikSpineGrp) """ tmp = IKfollowJnt.getParent() if tmp: tmp.setAttr("scaleX", 1) IKfollowJnt.setParent(world = True) pm.delete(tmp) """ constrain = pm.parentConstraint(dwCtrl, IK_chain[len(IK_chain)-1], IKfollowJnt) for attr in pm.listAttr(constrain, visible = True, keyable= True): if 'IKW' in attr: # print(attr) pm.connectAttr(dwCtrl.followJoint, '%s.%s' % (constrain,attr)) ikFound = True elif 'ctrl' in attr: # print(attr) pm.connectAttr(dwCtrl.followCtrl, '%s.%s' % (constrain,attr)) ##### ik pelvis # follow control on pelvis # duplicate first joint as follow_pelvis_joint pelvisIKjoint = pm.duplicate(IKjointList[0], parentOnly = True, name = (IKjointList[0].nodeName() + "_pelvis_follow_joint"))[0] pelvisIKjoint.jointOrient.set([0,0,0]) # duplicate down ctrl as pelvis ctrl pelvisIKctrlList = pm.duplicate(upCtrl, name = (upCtrl.nodeName() + "_pelvis")) pelvisIKctrl = pelvisIKctrlList[0] toDel = pm.listRelatives(pelvisIKctrl, children = True, type = "transform") pm.delete(toDel) manageCtrl.scaleShape(sel = pelvisIKctrl, scalX = True, scalY = True, scalZ = True, scale = 0.9) # parent pelvis ctrl under down ctrl pm.parent(pelvisIKctrl, upCtrl) helpers.createOneHelper(sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "insert") # add loc on IKjointList[0] IKpelvisJointLocGrp, IKpelvisJointLoc = helpers.createOneHelper(type = "loc", sel = IKjointList[0], freezeGrp = False, hierarchyParent = "child") # add loc on pelvis ctrl IKpelvisCtrlLocGrp, IKpelvisCtrlLoc = helpers.createOneHelper(type = "loc", sel = pelvisIKctrl, freezeGrp = False, hierarchyParent = "child") # parent constraint follow_pelvis_joint to locs IKpelvisConstraint = pm.parentConstraint(IKpelvisJointLoc, IKpelvisCtrlLoc, pelvisIKjoint) # add attributes on base controller pm.addAttr(upCtrl, ln = "_______" , attributeType = "enum", enumName = "CTRLS:") pm.addAttr(upCtrl, ln = "followJoint" , at = 'double', min = 0, max = 1, dv = 0) pm.addAttr(upCtrl, ln = "followCtrl" , at = 'double', min = 0, max = 1) pm.setAttr(upCtrl._______ , keyable = True, lock = True) pm.setAttr(upCtrl.followJoint, keyable = True) pm.setAttr(upCtrl.followCtrl, keyable = True) pelvisSubFollowNode = pm.createNode('plusMinusAverage', name = "pelvis_follow_mode_compense") pelvisSubFollowNode.setAttr("input1D[0]", 1) pelvisSubFollowNode.setAttr('operation', 2) pm.connectAttr(upCtrl.followJoint, pelvisSubFollowNode.input1D[1], f = True) pm.connectAttr(pelvisSubFollowNode.output1D, upCtrl.followCtrl, f = True) # connect attributes to constraint parent contraintList = pm.parentConstraint(IKpelvisConstraint, query = True, targetList = True ) # pprint(contraintList) weightAliasList = pm.parentConstraint(IKpelvisConstraint, query = True, weightAliasList = True ) # pprint(weightAliasList) # pprint(IKpelvisJointLoc) for i,c in enumerate(contraintList): if c == IKpelvisJointLoc: pm.connectAttr(upCtrl.followJoint, weightAliasList[i] ) elif c == IKpelvisCtrlLoc: pm.connectAttr(upCtrl.followCtrl, weightAliasList[i] ) ## constraint deformation system to follow ik # return good array of ik joint to parent on return IKfollowJnt, pelvisIKjoint
def __init__(self, chainJoints, prefix='tail', rigScale=1.0, doDynamic=False, smallestScalePercent=0.1, fkParenting=True, baseRig=None): """ :param chainJoints: list( str ), list of chain joints :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param smallestScalePercent: float, scale of smallest control at the end of chain compared to rigScale :param doDynamic: bool, setup dynamic curve :param fkParenting: bool, parent each control to previous one to make FK chain :param baseRig: instance of base.module.Base class :return: dictionary with rig module objects """ # :param chainCurve: str, name of chain cubic curve # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # collision point collisionPoint = int(len(chainJoints)) # make IK handle chainIk, effector, chainCurve = pm.ikHandle( n=prefix + '_IKH', sol='ikSplineSolver', sj=chainJoints[0], ee=chainJoints[-1], # -2 createCurve=True, numSpans=collisionPoint) # rename curve pm.rename(chainCurve, prefix + '_CRV') # create ctrlCurve ctrlCurve = pm.duplicate(chainCurve, n=prefix + 'Ctrl_CRV')[0] # make chain curve clusters chainCurveCVs = pm.ls(ctrlCurve + '.cv[*]', fl=1) numChainCVs = len(chainCurveCVs) chainCurveClusters = [] for i in range(numChainCVs): cls = pm.cluster(chainCurveCVs[i], n=prefix + 'Cluster%d' % (i + 1))[1] chainCurveClusters.append(cls) pm.hide(chainCurveClusters) # parent chain curve pm.parent(chainCurve, self.rigmodule.partsNoTransGrp) pm.parent(ctrlCurve, self.rigmodule.partsNoTransGrp) # make attach groups self.baseAttachGrp = pm.group(n=prefix + 'BaseAttach_GRP', em=1, p=self.rigmodule.partsGrp) pm.delete(pm.pointConstraint(chainJoints[0], self.baseAttachGrp)) # make controls chainControls = [] controlScaleIncrement = (1.0 - smallestScalePercent) / numChainCVs mainCtrlScaleFactor = 1.0 # 5.0 for i in range(numChainCVs): ctrlScale = rigScale * mainCtrlScaleFactor * ( 1.0 - (i * controlScaleIncrement)) ctrl = control.Control(prefix=prefix + '%d' % (i + 1), translateTo=chainCurveClusters[i], scale=ctrlScale, parent=self.rigmodule.controlsGrp, shape='sphere') chainControls.append(ctrl) # parent controls if fkParenting: for i in range(numChainCVs): if i == 0: continue pm.parent(chainControls[i].Off, chainControls[i - 1].C) # attach clusters for i in range(numChainCVs): pm.parent(chainCurveClusters[i], chainControls[i].C) # attach controls pm.parentConstraint(self.baseAttachGrp, chainControls[0].Off, mo=1) pm.hide(chainIk) pm.parent(chainIk, self.rigmodule.partsNoTransGrp) # add twist attribute twistAt = 'twist' pm.addAttr(chainControls[-1].C, ln=twistAt, k=1) pm.connectAttr(chainControls[-1].C + '.' + twistAt, chainIk + '.twist') # save class attribute self.chainCurve = chainCurve self.controlCurve = ctrlCurve if doDynamic: self.dynCurve = self.makeDynamic(prefix, baseRig, self.rigmodule, chainControls, chainCurveClusters) deform.blendShapeDeformer(self.dynCurve.getInputCurve(), [self.controlCurve], nodeName=prefix + 'BlendShape', frontOfChain=True) deform.blendShapeDeformer(self.chainCurve, [self.dynCurve.getOutputCurve()], nodeName=prefix + 'BlendShape', frontOfChain=True) else: deform.blendShapeDeformer(self.chainCurve, [self.controlCurve], nodeName=prefix + 'BlendShape', frontOfChain=True)
def __init__(self, cvList, skinGeo, prefix='face', headJnt='head_JNT', pointsNumber=5, scale=0.1, baseRig=None ): """ Build Facial Setup :param cvList: list of facial curves :param prefix: str, prefix to name new objects :param rigScale: float, scale factor for size of controls :param baseRig: instance of base.module.Base class """ cvList = pm.ls(cvList) skinGeo = pm.ls(skinGeo)[0] headJnt = pm.ls(headJnt)[0] # make rig module self.rigmodule = module.Module(prefix=prefix, baseObj=baseRig) # attributes self.spacing = 1.0 / (pointsNumber - 1) # setup deformation # geo setup faceGeo = pm.duplicate(skinGeo, n=prefix + '_GEO')[0] pm.parent(faceGeo, self.rigmodule.partsNoTransGrp) deform.blendShapeDeformer(skinGeo, [faceGeo], 'face_BS', frontOfChain=True) # joints setup headFaceJnt = pm.duplicate(headJnt, renameChildren=True)[0] jointsDuplicates = pm.listRelatives(headFaceJnt, c=True, ad=True) jointsDuplicates.append(headFaceJnt) for jnt in jointsDuplicates: pm.rename(jnt, str(jnt.name()).replace('_JNT1', 'Face_JNT')) pm.parent(jointsDuplicates[-1], self.rigmodule.jointsGrp) pm.skinCluster(faceGeo, headFaceJnt) faceGeoSkincluster = skin.findRelatedSkinCluster(faceGeo) pm.skinCluster(faceGeo, edit=True, ai=cvList, ug=True) faceGeoSkincluster.useComponents.set(1) pm.parent(pm.ls('*_CRVBase'), self.rigmodule.partsNoTransGrp) fullLocList = [] fullClusterList = [] for cv in pm.ls(cvList): pm.rebuildCurve(cv, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=0, kep=1, kt=0, s=4, d=1, tol=0.01) pm.rebuildCurve(cv, ch=0, rpo=1, rt=0, end=1, kr=0, kcp=1, kep=1, kt=0, s=4, d=3, tol=0.01) pm.parent(cv, self.rigmodule.partsNoTransGrp) locList = self.setupCurve(cv, pointsNumber) fullLocList.extend(locList) # cluster chainCurveCVs = pm.ls(cv + '.cv[*]', fl=1) numChainCVs = len(chainCurveCVs) curveClusters = [] for i in range(numChainCVs): cls = pm.cluster(chainCurveCVs[i], n=str(cv.name()) + 'Cluster%d' % (i + 1))[1] curveClusters.append(cls) fullClusterList.extend(curveClusters) clusterGrp = pm.group(fullClusterList, n='faceCluster_GRP', p=self.rigmodule.partsNoTransGrp) follicleList = [] for loc, cls in zip(fullLocList, fullClusterList): ctrl = control.Control(str(loc.name()).replace('_LOC', ''), translateTo=loc, shape='sphere', parent=self.rigmodule.controlsGrp, doModify=True, scale=scale) follicle = followCtrl.makeControlFollowSkin(skinGeo, ctrl.getControl(), cls)[-1] follicleList.extend([follicle]) follicleGrp = pm.group(follicleList, n='faceFollicle_GRP', p=self.rigmodule.partsNoTransGrp)
def jointsSetup(self): self.all_locs = [] self.all_joint = [] for each in self.all_guide: _joint = pm.joint(n=each.name().replace('guide', 'jnt__')) _loc = pm.spaceLocator(n=each.name().replace('guide', 'loc__')) pm.PyNode(_loc).getShape().localScaleX.set(0.2) pm.PyNode(_loc).getShape().localScaleY.set(0.2) pm.PyNode(_loc).getShape().localScaleZ.set(0.2) adb.changeColor_func(_loc, 'index', 14) pm.parent(_joint, w=True) self.all_joint.append(_joint) self.all_locs.append(_loc) for joint, guide in zip(self.all_joint, self.all_guide): pm.matchTransform(joint, guide, pos=True) pm.parent(joint, guide) for loc, guide in zip(self.all_locs, self.all_guide): pm.matchTransform(loc, guide, pos=True) pm.parentConstraint(guide, loc) pm.select(None) ## SCALING scaling_grp = pm.group(em=True, n='scaling__grp__') pm.parent('l__arm_clav__guide__root__grp__', 'l__arm_elbow__guide__root__grp__', 'l__arm_hand__guide__root__grp__', 'l__leg_main__guide__root__grp__', 'r__arm_clav__guide__root__grp__', 'r__arm_elbow__guide__root__grp__', 'r__arm_hand__guide__root__grp__', 'r__leg_main__guide__root__grp__', 'spine_guide__curve', scaling_grp) pm.PyNode(scaling_grp).setScale((0.05, 0.05, 0.05)) pm.parent(w=True) pm.delete(scaling_grp) ## ----------------------------------------------- ## SPINE SUITE pm.select(self.spine_curve, r=True) sel = pm.select(".cv[*]") cvs = pm.filterExpand(fullPath=True, sm=28) # Nombre de vertex sur la curve # nbCvs = len(cvs) oCollClusters = [pm.cluster(cvs[x]) for x in range(0, nbCvs)] self.all_spine_guide = [] for clus in oCollClusters: clus[1].v.set(0) spine_guide = pm.sphere(n='m__spine__guide_01', r=0.05)[0] self.all_spine_guide.append(spine_guide) pm.matchTransform(spine_guide, clus, pos=True) for oClus, spine in zip(oCollClusters, self.all_spine_guide): pm.parentConstraint(spine, oClus) for spine_guide in self.all_spine_guide: pm.select(spine_guide) mc.FreezeTransformations() pm.PyNode(self.all_spine_guide[1]).v.set(0) pm.PyNode(self.all_spine_guide[-2]).v.set(0) cluster_grp = pm.group(oCollClusters, n='spine_cls__grp__', w=1) all_spine_guide_grp = pm.group(self.all_spine_guide, n='spine_guide__grp__', w=1) self.all_guide.extend(self.all_spine_guide) ## Hide loc self.locs_grp = pm.group(n='x__locs_pos__grp__') pm.parent(self.all_locs, self.locs_grp) pm.PyNode(self.locs_grp).v.set(0) ## associate shader spine_shader = pm.shadingNode('lambert', asShader=True, n='yellow_guide_shader') pm.setAttr(spine_shader + ".incandescence", 0, 0.42, 0.06, type='double3') pm.select(pm.ls(type='nurbsSurface')) for spine_guide in pm.selected(): pm.select(spine_guide) pm.hyperShade(assign=spine_shader) @changeColor('index', col=(14)) def create_curve(): _curve_arm_1 = pm.curve(p=[(2.2, 5, -0.05), (1.45, 5, -0.05)], k=[0, 1], d=1) _curve_arm_2 = pm.curve(p=[(1.45, 5, -0.05), (0.5, 5, 0)], k=[0, 1], d=1) _curve_arm_4 = pm.curve(p=[(-2.2, 5, -0.05), (-1.45, 5, -0.05)], k=[0, 1], d=1) _curve_arm_5 = pm.curve(p=[(-1.45, 5, -0.05), (-0.5, 5, 0)], k=[0, 1], d=1) r_leg_thigh_curve = pm.curve(p=[(-0.4, 3.2, 0.05), (-0.4, 1.75, 0.185)], k=[0, 1], d=1) l_leg_thigh_curve = pm.curve(p=[(0.4, 3.2, 0.05), (0.4, 1.75, 0.185)], k=[0, 1], d=1) r_leg_knee_curve = pm.curve(p=[(-0.4, 1.75, 0.185), (-0.4, 0.35, 0)], k=[0, 1], d=1) l_leg_knee_curve = pm.curve(p=[(0.4, 1.75, 0.185), (0.4, 0.35, 0)], k=[0, 1], d=1) all_curves = [ _curve_arm_1, _curve_arm_2, _curve_arm_4, _curve_arm_5, r_leg_thigh_curve, l_leg_thigh_curve, r_leg_knee_curve, l_leg_knee_curve ] self.curves_grp = pm.group(em=True, n='x__curves__grp__', w=True) pm.select(self.all_joint, r=True) pm.select(all_curves, add=True) mc.SmoothBindSkin() pm.parent(_curve_arm_1, _curve_arm_2, _curve_arm_4, _curve_arm_5, r_leg_thigh_curve, l_leg_thigh_curve, r_leg_knee_curve, l_leg_knee_curve, self.spine_curve, cluster_grp, self.curves_grp) return self.curves_grp create_curve() guide_scale_grp = pm.group(em=True, n='x__guide__grp__') pm.parent('l__arm_clav__guide__root__grp__', 'l__arm_elbow__guide__root__grp__', 'l__arm_hand__guide__root__grp__', 'l__leg_main__guide__root__grp__', 'r__arm_clav__guide__root__grp__', 'r__arm_elbow__guide__root__grp__', 'r__arm_hand__guide__root__grp__', 'r__leg_main__guide__root__grp__', 'spine_guide__grp__', guide_scale_grp) return guide_scale_grp
startFrame += 1 ## Book Set Up ## import pymel.core as pm import tak_misc reload(tak_misc) # Page bulgeClsts = [] selLs = pm.ls(sl=True) for sel in selLs: pm.select(sel, r=True) ffdNodes = pm.lattice(sel, divisions=[2,5,2], objectCentered=True, ldv=[2,2,2], n=sel+"_ffd") ffdNodes[0].setAttr("local", 0) clst = pm.cluster("%s.pt[0:1][1][0]" %(ffdNodes[1]), "%s.pt[0:1][1][1]" %(ffdNodes[1]), n=sel+"_ffd_clst") pm.addAttr(sel.split("_")[0]+"_ctrl", ln="bulge", at="float", keyable=True) pm.connectAttr(sel.split("_")[0]+"_ctrl"+".bulge", clst[0]+"Handle.translateX") # Page1~5 selLs = pm.ls(sl=True) for sel in selLs: pm.select(sel, r=True) ffdNodes = pm.lattice(sel, divisions=[2,5,2], objectCentered=True, ldv=[2,2,2], n=sel+"_ffd") ffdNodes[0].setAttr("local", 0) clst = pm.cluster("%s.pt[0:1][1][0]" %(ffdNodes[1]), "%s.pt[0:1][1][1]" %(ffdNodes[1]), n=sel+"_ffd_clst") pm.addAttr(sel.rsplit("_", 1)[0] + "_ctrl", ln="bulge", at="float", keyable=True) pm.connectAttr(sel.rsplit("_", 1)[0]+"_ctrl"+".bulge", clst[0]+"Handle.translateX")
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 CreateSurface(pos1, pos2, Div=10): try: pm.select(pos1) tempPos = pm.cluster(n='Temp')[1] JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos1, tempPos)) JntPos1 = pm.createNode('joint', n=(pos1 + '_Pos1Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos1)) pm.makeIdentity(JntPos1, a=1, t=1, r=1, s=1) pm.delete(tempPos) try: pm.select(pos2) tempPos = pm.cluster(n='Temp')[1] JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) except: tempPos = pm.createNode('transform', n='Temp') pm.delete(pm.parentConstraint(pos2, tempPos)) JntPos2 = pm.createNode('joint', n=(pos2 + '_Pos2Jnt')) pm.delete(pm.parentConstraint(tempPos, JntPos2)) pm.makeIdentity(JntPos2, a=1, t=1, r=1, s=1) pm.delete(tempPos) pm.parent(JntPos2, JntPos1) pm.joint(JntPos1, e=1, oj='xyz', secondaryAxisOrient='yup') pm.joint(JntPos2, e=1, oj='none', ch=1, zso=1) distanceND = pm.createNode('distanceBetween') JntPos1.worldMatrix[0] >> distanceND.inMatrix1 JntPos2.worldMatrix[0] >> distanceND.inMatrix2 Dist = distanceND.distance.get() surface = pm.nurbsPlane(w=Dist, lr=.01, u=Div, ax=(0, 1, 0), ch=0) print surface bsSurface = pm.duplicate(surface) print bsSurface pm.blendShape(bsSurface, surface, foc=1, n=(str(bsSurface[0]) + '_Blendshape'), w=(0, 1)) pm.delete(pm.parentConstraint(JntPos1, JntPos2, surface[0])) pm.delete(JntPos1, JntPos2) fols = [] ctrls = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i) + '_Follicle'), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = surface[0] geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) fols.append(fol) Ctrl = mel.eval( "sphere -esw 360 -r 0.3 -d 1 -ut 0 -tol 0.01 -s 4 -nsp 2 -ch 0;") pm.PyNode(Ctrl[0]) Ctrl = pm.rename(Ctrl[0], 'Follicle_' + str(i) + '_Ctrl') pm.delete(pm.parentConstraint(fol, Ctrl)) Grp = ZeroOut(Ctrl) ctrls.append(Ctrl) try: Shaps = pm.listRelatives(Ctrl, s=1)[0] Shaps.overrideEnabled.set(1) Shaps.overrideShading.set(0) Shaps.overrideColor.set(4) Shaps.overrideEnabled.lock(True) Shaps.overrideShading.lock(True) Shaps.overrideColor.lock(True) except: pass pm.select(cl=1) pm.parent(Grp, fol) RevGrp = RevGroup(Ctrl) SknJnts = [] for i in range(0, Div): val = ((.5 / float(Div)) * (i + 1) * 2) - ((.5 / float(Div * 2)) * 2) fol = pm.createNode('transform', n=('Tst_' + str(i)), ss=1) folShape = pm.createNode('follicle', n=fol.name() + 'Shape', p=fol, ss=1) geo = bsSurface[0] geo.local >> folShape.inputSurface geo.worldMatrix[0] >> folShape.inputWorldMatrix folShape.outRotate >> fol.rotate folShape.outTranslate >> fol.translate fol.inheritsTransform.set(False) folShape.parameterV.set(0.5) folShape.parameterU.set(val) pm.select(cl=1) jnt = pm.joint(n=('Follicle_' + str(i) + '_Jnt')) SknJnts.append(jnt) pm.delete(pm.parentConstraint(fol, jnt)) #pm.delete(fol) ZeroOut(jnt) pm.makeIdentity(jnt, a=1, t=1, r=1, s=1) for i in range(0, Div): ctrls[i].t >> SknJnts[i].t ctrls[i].r >> SknJnts[i].r ctrls[i].s >> SknJnts[i].s pm.skinCluster(SknJnts, bsSurface, mi=3, omi=0, tsb=1, dr=10)
import pymel.core as pm jnt = pm.PyNode('joint 2') sel = pm.ls(sl=1)[0] his = pm.listHistory(sel) Skin = pm.ls(his, type='skinCluster')[0] jnts = pm.skinCluster(Skin, q=1, inf=1) vtxCnt = pm.polyEvaluate(sel, v=1) pm.select(cl=1) pm.skinCluster(Skin, siv=jnt, e=1) vtx = pm.ls(sl=1, fl=1) pos = pm.xform(jnt, q=1, ws=1, t=1) cl = pm.cluster(n=jnt + 'CL') cl[1].origin.set(pos) cl[1].rotatePivot.set(pos) cl[1].scalePivot.set(pos) clSet = pm.listConnections(cl[0], t='objectSet') for i in vtx: skinData = pm.skinPercent(Skin, i, q=1, t=jnt, v=1) pm.percent(cl[0], i, v=skinData) print skinData
def rigSpineCmd( prefix='spine_', suffix='', hasStretch=False, worldSpace=False ): exp_template = '' labels = { 'end_control' : prefix + 'control_end' + suffix, 'mid_control' : prefix + 'control_mid' + suffix, 'ik' : prefix + 'ik' + suffix, 'curve' : prefix + 'curve' + suffix, 'cluster' : prefix + 'cluster' + suffix, 'clusters' : prefix + 'clusters' + suffix, 'parent' : prefix + 'parent' + suffix, 'expression' : prefix + 'controls' + suffix + '_EXP', } try: start_joint, end_joint = pm.ls(sl=1,type="joint") except ValueError: raise ValueError, "Select the start and end joints to setup." parent_joint = start_joint.getParent() mid_joint = start_joint.getChildren(type='joint')[0] if parent_joint is None: raise ValueError, "Start joint must have a parent transform." main_ik, main_ee, main_curve = pm.ikHandle( n=labels['ik'], sj=start_joint, ee=end_joint, sol='ikSplineSolver', pcv=True, numSpans=1, dh=1 ) main_curve.rename( labels['curve'] ) cluster0, handle0 = pm.cluster( main_curve+'.cv[0]', main_curve+'.cv[1]', n=labels['cluster']+'0', en=1, rel=1 ) cluster1, handle1 = pm.cluster( main_curve+'.cv[1]', main_curve+'.cv[2]', n=labels['cluster']+'1', en=1, rel=1 ) cluster2, handle2 = pm.cluster( main_curve+'.cv[4]', n=labels['cluster']+'2', en=1, rel=1 ) start_point = start_joint.getRotatePivot(ws=1) * start_joint.getRotatePivot(ws=1)[-1] end_point = end_joint.getRotatePivot(ws=1) * end_joint.getRotatePivot(ws=1)[-1] handle1_point = handle1.getRotatePivot(ws=1) * handle1.getRotatePivot(ws=1)[-1] length = start_point.distanceTo( end_point ) # -- build controls control = pm.circle( n=labels['end_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0] control.translate.set( end_point ) control.rotateOrder.set(1) mid_control = pm.circle( n=labels['mid_control'], radius=(length / 2), normal=(0,1,0), ch=0 )[0] mid_control.translate.set( handle1_point ) pm.makeIdentity( [ control, mid_control ], apply=True, s=0, r=0, t=1, n=0 ) # -- add control attributes control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- constrain controls pm.pointConstraint( control, handle2, offset=(0,0,0), weight=1 ) pm.aimConstraint( handle1, control, weight=1, aimVector=(0,-1,0), skip='y' ) pm.pointConstraint( mid_control, handle1, offset=(0,0,0), weight=1 ) pm.aimConstraint( handle0, mid_control, weight=1, aimVector=(0,1,0) ) if worldSpace: pm.pointConstraint( parent_joint, handle0, maintainOffset=1, weight=1 ) # -- group and parent nodes cluster_group = pm.group( handle0, handle1, handle2, name=labels['clusters'] ) parent_group = pm.group( name=labels['parent'], em=1 ) parent_group.rotatePivot.set( parent_joint.getRotatePivot(ws=1) ) pm.parent( control, mid_control, main_ik, main_curve, cluster_group, parent_group ) if not worldSpace: pm.parentConstraint( parent_joint, parent_group, w=1, mo=1 ) if hasStretch: control.addAttr( "stretch", at='double', k=1, dv=0, min=-1, max=1 ) exp_template += EXP_SPINE_STRETCH exp_template += EXP_SPINE exp_str = exp_template \ % { 'control' : control, 'start_joint' : start_joint, 'end_joint' : end_joint, 'mid_joint' : mid_joint, 'parent_joint' : parent_joint, 'main_ik' : main_ik, 'shape' : control.getShape(), 'mid_shape' : mid_control.getShape(), } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) resetIkSetupCmd(end_joint, control) # -- make things look pretty for n in pm.ls( [main_ik, main_curve, cluster_group], dag=1, type="transform" ): n.visibility.set(0) addToSet( [control, mid_control], 'controlsSet' ) control.displayHandle.set(1) setAttrs( control, ['rx','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( mid_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(mid_control.v, keyable=0 ) pm.color( ud=CntlColors.center ) pm.select( control, r=1 ) return [ control, mid_control ]
def _create(baseName, fkControls=None, endTransform=None, createGuideCurve=False, ikSpline=True, ikSplineJoints=[], ikSpline_numOfJoints=60): """Creates an advanced FK setup. kwargs: fkControls - list of <pymel transforms> - the positioned controls endTransform - pymel transforms - a transform representing the end of the setup """ #kName = KName() relationshipDic = {} guideTransforms = fkControls + [endTransform] rigGroup = pymel.createNode('transform') rigGroup.rename(baseName + '_controlRig') ## CREATE BASIC CONTROLS ======================================= relationshipDic[endTransform] = {} for i, fkControl in enumerate(fkControls): relationshipDic[fkControl] = {} try: fkControl.sx.set(lock=True, keyable=False) fkControl.sy.set(lock=True, keyable=False) fkControl.sz.set(lock=True, keyable=False) fkControl.v.set(lock=True, keyable=False) except: pass ## CREATE ZERO GROUP --------------------------------------- # create zero out group zeroGroup = pymel.createNode('transform') zeroGroup.rename(fkControl.nodeName() + '_zro') # snap zeroGroup ka_transforms.snap(t=1, r=1, snapTarget=fkControl, snapObjects=zeroGroup) # parent zeroGroup if i == 0: pymel.parent(zeroGroup, rigGroup) else: if fkControl.getParent(): pymel.parent(zeroGroup, fkControl.getParent()) pymel.parent(fkControl, zeroGroup) relationshipDic[fkControl]['zeroGroup'] = zeroGroup ## CREATE SHADOW GROUP --------------------------------------- # create shadow group shdwGroup = pymel.createNode('transform') shdwGroup.rename(fkControl.nodeName() + '_shdw') # snap shdwGroup ka_transforms.snap(t=1, r=1, snapTarget=fkControl, snapObjects=shdwGroup) # parent shdwGroup pymel.parent(shdwGroup, zeroGroup) pymel.orientConstraint(fkControl, shdwGroup) pymel.parent(fkControl.getChildren(type='transform'), shdwGroup) relationshipDic[fkControl]['shdwGroup'] = zeroGroup ## CREATE GUIDE CURVE ======================================= if createGuideCurve: lastI = len(guideTransforms) - 1 for i, guideTransform in enumerate(guideTransforms): # create orientationLocator ------------------------- orientationLocatorShape = pymel.createNode('locator') orientationLocatorShape.localScaleX.set(0.5) orientationLocatorShape.localScaleY.set(0.5) orientationLocatorShape.localScaleZ.set(0.5) orientationLocator = orientationLocatorShape.getParent() orientationLocator.rename(guideTransform.nodeName() + '_orientationLocator') orientationLocator.v.set(0) ka_transforms.snap(t=1, r=1, snapTarget=guideTransform, snapObjects=orientationLocator) pymel.parent(orientationLocator, guideTransform) relationshipDic[guideTransform][ 'orientationLocator'] = orientationLocator # create orientationLocator worldSpace position vector product orientationLocator_worldSpaceVectorProduct = pymel.createNode( 'vectorProduct') orientationLocator_worldSpaceVectorProduct.rename( orientationLocator.nodeName() + '_worldSpaceVectorProduct') orientationLocator_worldSpaceVectorProduct.operation.set(4) orientationLocator.worldMatrix[ 0] >> orientationLocator_worldSpaceVectorProduct.matrix relationshipDic[guideTransform][ 'orientationLocator_worldSpaceVectorProduct'] = orientationLocator_worldSpaceVectorProduct # create orientationLocator_backHandle ------------------------- if i != 0: orientationLocator_backHandleShape = pymel.createNode( 'locator') orientationLocator_backHandleShape.localScaleX.set(0.2) orientationLocator_backHandleShape.localScaleY.set(0.2) orientationLocator_backHandleShape.localScaleZ.set(0.2) orientationLocator_backHandle = orientationLocator_backHandleShape.getParent( ) orientationLocator_backHandle.rename( guideTransform.nodeName() + 'orientationLocator_backHandle') orientationLocator_backHandle.v.set(0) ka_transforms.snap(t=1, r=1, snapTarget=guideTransform, snapObjects=orientationLocator_backHandle) pymel.parent(orientationLocator_backHandle, orientationLocator) relationshipDic[guideTransform][ 'orientationLocator_backHandle'] = orientationLocator_backHandle # create orientationLocator_frontHandle ------------------------- if i != lastI: orientationLocator_frontHandleShape = pymel.createNode( 'locator') orientationLocator_frontHandleShape.localScaleX.set(0.2) orientationLocator_frontHandleShape.localScaleY.set(0.2) orientationLocator_frontHandleShape.localScaleZ.set(0.2) orientationLocator_frontHandle = orientationLocator_frontHandleShape.getParent( ) orientationLocator_frontHandle.rename( guideTransform.nodeName() + 'orientationLocator_frontHandle') orientationLocator_frontHandle.v.set(0) ka_transforms.snap(t=1, r=1, snapTarget=guideTransform, snapObjects=orientationLocator_frontHandle) pymel.parent(orientationLocator_frontHandle, orientationLocator) relationshipDic[guideTransform][ 'orientationLocator_frontHandle'] = orientationLocator_frontHandle # CREATE TIGHTNESS ATTRIBUTE ON CONTROLLERS for fkControl in fkControls: fkControl.addAttr('addLength', minValue=0.0, defaultValue=0.0) fkControl.addAttr('positionBetween', minValue=-1.0, maxValue=1.0, defaultValue=0.0) fkControl.addAttr('curveTightness', minValue=0.0, maxValue=1.0, defaultValue=0.0) fkControl.addLength.set(keyable=True) fkControl.positionBetween.set(keyable=True) fkControl.curveTightness.set(keyable=True) guideCurveCvDrivers = [] # orient the orientation locators with aim betweens for i, guideTransform in enumerate(guideTransforms): orientationLocator = relationshipDic[guideTransform][ 'orientationLocator'] if i == 0: nextFkControl = guideTransforms[i + 1] previousFkControl = None orientationLocator_frontHandle = relationshipDic[ guideTransform]['orientationLocator_frontHandle'] orientationLocator_backHandle = None nextOrientationLocator = relationshipDic[nextFkControl][ 'orientationLocator'] previousOrientationLocator = None guideCurveCvDrivers.extend( [orientationLocator, orientationLocator_frontHandle]) elif i == lastI: nextFkControl = None previousFkControl = guideTransforms[i - 1] orientationLocator_frontHandle = None orientationLocator_backHandle = relationshipDic[ guideTransform]['orientationLocator_backHandle'] nextOrientationLocator = None previousOrientationLocator = relationshipDic[ previousFkControl]['orientationLocator'] guideCurveCvDrivers.extend( [orientationLocator_backHandle, orientationLocator]) else: nextFkControl = guideTransforms[i + 1] previousFkControl = guideTransforms[i - 1] orientationLocator_frontHandle = relationshipDic[ guideTransform]['orientationLocator_frontHandle'] orientationLocator_backHandle = relationshipDic[ guideTransform]['orientationLocator_backHandle'] nextOrientationLocator = relationshipDic[nextFkControl][ 'orientationLocator'] previousOrientationLocator = relationshipDic[ previousFkControl]['orientationLocator'] guideCurveCvDrivers.extend([ orientationLocator_backHandle, orientationLocator, orientationLocator_frontHandle ]) # create aim between constraints if i != 0 and i != lastI: ka_constraints.constrain( [nextFkControl, previousFkControl, orientationLocator], aimBetween=True) # Set Driven Key drivenKeyX = pymel.createNode('animCurveUU', ) drivenKeyYZ = pymel.createNode('animCurveUU', ) pymel.setKeyframe(drivenKeyX, value=0.333, float=0.0) pymel.setKeyframe(drivenKeyX, value=0.0, float=1.0) drivenKeyX.tangentType.set(18, ) drivenKeyX.weightedTangents.set(False, ) pymel.setKeyframe(drivenKeyYZ, value=0.0, float=0.0) pymel.setKeyframe(drivenKeyYZ, value=0.0, float=1.0) drivenKeyYZ.tangentType.set(18, ) drivenKeyYZ.weightedTangents.set(False, ) if i == lastI: guideTransforms[-2].curveTightness >> drivenKeyX.input guideTransforms[-2].curveTightness >> drivenKeyYZ.input else: guideTransform.curveTightness >> drivenKeyX.input guideTransform.curveTightness >> drivenKeyYZ.input # drive orientationLocator_Handles by local distance (in 1 axis) if nextOrientationLocator: nextOrientationLocator_worldSpaceVectorProduct = relationshipDic[ nextFkControl][ 'orientationLocator_worldSpaceVectorProduct'] localSpace_vectorProduct = pymel.createNode('vectorProduct') localSpace_vectorProduct.operation.set(4) nextOrientationLocator_worldSpaceVectorProduct.output >> localSpace_vectorProduct.input1 orientationLocator.worldInverseMatrix[ 0] >> localSpace_vectorProduct.matrix multiplyDivide = pymel.createNode('multiplyDivide') localSpace_vectorProduct.output >> multiplyDivide.input1 drivenKeyX.output >> multiplyDivide.input2X drivenKeyYZ.output >> multiplyDivide.input2Y drivenKeyYZ.output >> multiplyDivide.input2Z multiplyDivide.output >> orientationLocator_frontHandle.t if previousOrientationLocator: previousOrientationLocator_worldSpaceVectorProduct = relationshipDic[ previousFkControl][ 'orientationLocator_worldSpaceVectorProduct'] localSpace_vectorProduct = pymel.createNode('vectorProduct') localSpace_vectorProduct.operation.set(4) previousOrientationLocator_worldSpaceVectorProduct.output >> localSpace_vectorProduct.input1 orientationLocator.worldInverseMatrix[ 0] >> localSpace_vectorProduct.matrix multiplyDivide = pymel.createNode('multiplyDivide') localSpace_vectorProduct.output >> multiplyDivide.input1 drivenKeyX.output >> multiplyDivide.input2X drivenKeyYZ.output >> multiplyDivide.input2Y drivenKeyYZ.output >> multiplyDivide.input2Z multiplyDivide.output >> orientationLocator_backHandle.t # CREATE THE ACTUAL GUIDE CURVE numberOfPoints = ((len(fkControls) - 1) * 3) + 4 curvePointList = [] for driverTransform in guideCurveCvDrivers: position = pymel.xform(driverTransform, query=True, translation=True, worldSpace=True) curvePointList.append(tuple(position)) #guideCurve = pymel.curve(degree=3, p=curvePointList) guideCurve = pymel.curve(degree=7, p=curvePointList) guideCurve.rename(baseName + '_ikCurve') guideCurveShape = guideCurve.getShape() guideCurve.inheritsTransform.set(0) pymel.parent(guideCurve, rigGroup) for i, driverTransform in enumerate(guideCurveCvDrivers): pymel.cluster(guideCurveShape.cv[i], wn=(driverTransform, driverTransform), bindState=True) if ikSpline: curveInfoNode = pymel.createNode('curveInfo') guideCurve.worldSpace[0] >> curveInfoNode.inputCurve curveLength = curveInfoNode.arcLength.get() if not ikSplineJoints: curveLengthSegment = curveLength / (ikSpline_numOfJoints - 1) for i in range(ikSpline_numOfJoints): joint = pymel.createNode('joint') joint.rename(baseName + str(i) + '_ikSpline_jnt') if ikSplineJoints: joint.tx.set(i * curveLengthSegment) pymel.parent(joint, ikSplineJoints[-1]) ikSplineJoints.append(joint) pymel.parent(ikSplineJoints[0], rigGroup) ikHandel, ikEffector = pymel.ikHandle(startJoint=ikSplineJoints[0], endEffector=ikSplineJoints[-2], solver='ikSplineSolver', curve=guideCurve, createCurve=False) ikHandel.dTwistControlEnable.set(1) ikHandel.dWorldUpType.set(4) ikHandel.dWorldUpAxis.set(3) ikHandel.dTwistValueType.set(1) ikHandel.v.set(0) pymel.parent(ikHandel, fkControls[0]) # make a group to dictate the roll start of the ik spline twistGroupStart = pymel.createNode('transform') twistGroupStart.rename(baseName + '_twistStart') ka_transforms.snap(twistGroupStart, fkControls[0], t=1, r=1) pymel.parent(twistGroupStart, fkControls[0]) twistGroupStart.rx.set(90) # make a group to dictate the roll end of the ik spline twistGroupEnd = pymel.createNode('transform') twistGroupEnd.rename(baseName + '_twistEnd') ka_transforms.snap(twistGroupEnd, fkControls[-1], t=1, r=1) pymel.parent(twistGroupEnd, fkControls[-1]) twistGroupEnd.rx.set(90) twistGroupStart.worldMatrix[0] >> ikHandel.dWorldUpMatrix twistGroupEnd.worldMatrix[0] >> ikHandel.dWorldUpMatrixEnd curveLengthSegment = curveLength / (len(ikSplineJoints) - 1) segmentMultiplyDivide = pymel.createNode('multiplyDivide') curveInfoNode.arcLength >> segmentMultiplyDivide.input1X segmentMultiplyDivide.input2X.set(1.0 / (len(ikSplineJoints) - 1)) for i, joint in enumerate(ikSplineJoints): if i != 0: jointLengthMultiplyDivide = pymel.createNode('multiplyDivide') segmentMultiplyDivide.outputX >> jointLengthMultiplyDivide.input1X jointLengthMultiplyDivide.input2X.set(curveLengthSegment / joint.tx.get()) jointLengthMultiplyDivide.outputX >> joint.tx if i == len(ikSplineJoints) - 1: jointLengthMultiplyDivide.input2X.set( jointLengthMultiplyDivide.input2X.get() * 0.75) pymel.aimConstraint(endTransform, ikSplineJoints[-2], worldUpType='objectrotation', worldUpObject=endTransform) pymel.pointConstraint(endTransform, ikSplineJoints[-1]) #cmds.aimConstraint( 'cone1', 'surf2', 'cube2', w=.1 ) return rigGroup
def rigLimbCmd( prefix='leg_', suffix=None, side=LEFT_SIDE, hasStretch=False, hasFootRoll=False, footRollMode=FOOTROLL_AUTO ): suffix = suffix or ('_l','_r')[side] exp_template = "" labels = { 'control' : prefix + 'control' + suffix, 'aimControl' : prefix + 'aim' + suffix, 'ik' : prefix + 'ik' + suffix, 'ikEnd' : prefix + 'ik_end' + suffix, 'expression' : prefix + 'control' + suffix + '_EXP', 'guideJointIk' : prefix + 'ik_guide_', 'guideJoint' : prefix + 'guide_', 'ikStretch' : prefix + 'ik_stretch' + suffix, 'locStart' : prefix + 'loc_start' + suffix, 'locMid' : prefix + 'loc_mid' + suffix, 'locEnd' : prefix + 'loc_end' + suffix, 'locGuide' : prefix + 'loc_guide' + suffix, 'ikGuide' : prefix + 'ik_guide' + suffix, } try: start_joint, end_joint = pm.ls(sl=1,type="joint") except ValueError: raise ValueError, "Select the start and end joints to setup." mid_joint = end_joint.getParent() parent_joint = start_joint.getParent() unit_scale = start_joint.getRotatePivot(ws=1)[-1] # -- positions and length start_point = start_joint.getRotatePivot(ws=1) * unit_scale end_point = end_joint.getRotatePivot(ws=1) * unit_scale mid_point = mid_joint.getRotatePivot(ws=1) * unit_scale length = start_point.distanceTo( end_point ) # -- Create Control control = createNurbsShape( labels['control'], 'sphere', size=length*.2 ) control2 = createNurbsShape( labels['control'], 'locator', size=length*.3 ) pm.parent( control2.getShape(), control, r=1, s=1 ) pm.delete( control2 ) control.translate.set( end_point ) pm.makeIdentity( control, apply=True, s=0, r=0, t=1, n=0 ) control.addAttr( "ikBlend", at='double', k=1, dv=0, min=0, max=1 ) control.addAttr( "orientBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- Create Aim Control v1 = end_point - start_point v2 = mid_point - start_point v3 = v1.cross( v2 ) v4 = v3.cross( v1 ) aim_point = start_point + ( v4.normal() * length * 1.5 ) aim_control = createNurbsShape( labels['aimControl'], 'arrow', size=length/5 ) pm.xform( aim_control, t=aim_point ) pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 ) pm.aimConstraint( mid_joint, aim_control, weight=1, aimVector=(0, 0, 1) ) # -- Create Aim Line aim_line = pm.curve( name=labels['aimControl']+'_line', d=1, p=[aim_point, mid_point], k=[0, 1] ) line_cluster0, line_handle0 = pm.cluster( aim_line+'.cv[0]', n=labels['aimControl']+'_line_0', en=1, rel=1 ) line_cluster1, line_handle1 = pm.cluster( aim_line+'.cv[1]', n=labels['aimControl']+'_line_1', en=1, rel=1 ) pm.pointConstraint( aim_control, line_handle0, offset=(0,0,0), weight=1 ) pm.pointConstraint( mid_joint, line_handle1, offset=(0,0,0), weight=1 ) line_group0 = pm.group( line_handle0, name=line_handle0.name() + "_grp" ) line_group1 = pm.group( line_handle1, name=line_handle0.name() + "_grp" ) pm.parent( [aim_line, line_group0, line_group1, aim_control] ) line_group0.v.set(0) line_group1.v.set(0) setAttrs( line_group0, ['t','r','s','v'], lock=1 ) setAttrs( line_group1, ['t','r','s','v'], lock=1 ) setAttrs( aim_line, ['t','r','s','v'], lock=1 ) aim_line.overrideEnabled.set(1) aim_line.overrideDisplayType.set(1) if hasStretch: guide_ik_start = pm.duplicate( start_joint, rc=1 )[0] guide_ik_mid, guide_ik_end = pm.ls( guide_ik_start, dag=1 )[1:3] for n in pm.ls( guide_ik_start, dag=1 ): pm.rename( n, labels['guideJointIk'] + n[:-1] ) guide_start = pm.duplicate( start_joint, rc=1 )[0] guide_mid, guide_end = pm.ls( guide_start, dag=1 )[1:3] for n in pm.ls( guide_start, dag=1 ): pm.rename( n, labels['guideJoint'] + n[:-1] ) parent_group = pm.group( name=labels['ikStretch'], em=1 ) if parent_joint is not None: parent_group.setRotatePivot( parent_joint.getRotatePivot(ws=1) * unit_scale, ws=1 ) pm.parentConstraint( parent_joint, parent_group, weight=1 ) pm.parent( guide_ik_start, guide_start, parent_group ) # -- build a temp joint chain to get loc_mid position loc_start = pm.group( n=labels['locStart'], em=1 ) pm.parent( loc_start, parent_group ) loc_start.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 ) pm.aimConstraint( control, loc_start, weight=1, aimVector=(1,0,0) ) loc_end = pm.group( n=labels['locEnd'], em=1, parent=loc_start ) loc_end.setRotatePivot( start_joint.getRotatePivot( ws=1) * unit_scale, ws=1 ) pm.pointConstraint( control, loc_end, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.select(cl=1) temp_start = pm.joint( p=start_point ) temp_end = pm.joint( p=end_point ) pm.joint( temp_start, edit=1, oj='xyz', secondaryAxisOrient='yup', ch=1 ) pm.pointConstraint( mid_joint, temp_end, offset=(0,0,0), skip=('y','z'), weight=1 ) loc_mid_point = temp_end.getRotatePivot(ws=1) * unit_scale pm.delete( temp_start ) # -- create the mid locator loc_mid = pm.group( n=labels['locMid'], em=1)#spaceLocator() loc_mid.translate.set( loc_mid_point ) pm.makeIdentity( apply=True, s=0, r=0, t=1, n=0 ) pm.pointConstraint( loc_start, loc_mid, mo=1, weight=1 ) pm.pointConstraint( loc_end, loc_mid, mo=1, weight=1 ) # -- create the guide locator loc_guide = pm.group( n=labels['locGuide'], em=1) guide_constraint = pm.pointConstraint( loc_mid, loc_guide, offset=(0,0,0), weight=1 ) pm.pointConstraint( guide_ik_mid, loc_guide, offset=(0,0,0), weight=1 ) pm.parent( loc_mid, loc_guide, parent_group ) guide_ik, guide_ee = pm.ikHandle( sj=guide_ik_start, ee=guide_ik_end, solver="ikRPsolver", dh=1 ) pm.poleVectorConstraint( aim_control, guide_ik, weight=1 ) pm.delete( guide_ik_end ) pm.rename( guide_ik, labels['ikGuide'] ) # -- SET STRETCH BLEND START guide_ik.addAttr( "stretchStart", at='double', k=1 ) guide_ik.stretchStart.set( loc_end.tx.get() ) # -- SET STRETCH BLEND END guide_ik.addAttr( "stretchEnd", at='double', k=1 ) guide_ik.stretchEnd.set( loc_end.tx.get()*1.1 ) # -- SET STRETCH BLEND END guide_ik.addAttr( "stretchFactor", at='double', k=1 ) guide_ik.stretchFactor.set( 0.22 ) # -- setup guide joints pm.aimConstraint( loc_guide, guide_start, weight=1, aimVector=(1,0,0) ) pm.aimConstraint( loc_end, guide_mid, weight=1, aimVector=(1,0,0) ) pm.pointConstraint( loc_guide, guide_mid, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.pointConstraint( loc_end, guide_end, offset=(0,0,0), skip=('y','z'), weight=1 ) pm.parent( guide_ik, loc_end ) pm.parent( guide_ik, control ) # -- add stretch addtributes start_joint.addAttr( "stretch", at='double', k=1, dv=0 ) mid_joint.addAttr( "stretch", at='double', k=1, dv=0 ) control.addAttr( "stretchBlend", at='double', k=1, dv=0, min=0, max=1 ) # -- build the expression exp_template += EXP_STRETCH \ % { 'guide_ik' : guide_ik, 'loc_end' : loc_end, 'constraint' : guide_constraint, # -- we only need these names for the constraint attribute names 'guide_ik_mid' : guide_ik_mid.split('|')[-1], 'loc_mid' : loc_mid.split('|')[-1], 'control' : control, 'start_joint' : start_joint, 'mid_joint' : mid_joint, 'end_joint' : end_joint, 'guide_mid' : guide_mid, 'guide_end' : guide_end, } # -- make things look pretty for n in pm.ls( [ parent_group, guide_ik ], dag=1 ): n.visibility.set(0) for obj in guide_end.getChildren( type='joint' ): try: pm.delete( obj ) except: pass # -- hook up the original joints main_ik, main_ee = pm.ikHandle( sj=start_joint, ee=end_joint, solver="ikRPsolver", dh=1 ) pm.poleVectorConstraint( aim_control, main_ik, weight=1 ) pm.rename( main_ik, labels['ik'] ) end_ik, end_ee = pm.ikHandle( sj=end_joint, ee=end_joint.getChildren(type='joint')[0], solver="ikRPsolver", dh=1 ) pm.rename( end_ik, labels['ikEnd'] ) pm.parent( main_ik, end_ik, control ) # -- fill out the expression template exp_template += EXP_IKFK + EXP_VIS exp_str = exp_template \ % { #'guide_ik' : guide_ik, #'loc_end' : loc_end, #'constraint' : guide_constraint, #we only need these names for the constraint attribute names #'guide_ik_mid' : guide_ik_mid.split('|')[-1], #'loc_mid' : loc_mid.split('|')[-1], 'control' : control, 'start_joint' : start_joint, 'mid_joint' : mid_joint, 'end_joint' : end_joint, #'guide_mid' : guide_mid, #'guide_end' : guide_end, 'main_ik' : main_ik, 'end_ik' : end_ik, 'shape1' : control.getChildren(type="nurbsCurve")[0], 'shape2' : control.getChildren(type="nurbsCurve")[1], } pm.expression( s=exp_str, o=control, n=labels['expression'], a=1, uc='all' ) if hasFootRoll: rigFootRoll( end_joint, control, prefix, suffix, side=side, footRollMode=footRollMode ) resetIkSetupCmd(end_joint, control) resetIkSetupCmd(start_joint, aim_control) # -- make things look pretty for n in pm.ls( control, dag=1, type="transform" )[1:]: if n.type() != "transform": n.visibility.set(0) setAttrs( control, ['sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) setAttrs( aim_control, ['rx','ry','rz','sx','sy','sz'], channelBox=0, keyable=0, lock=1 ) pm.setAttr(control.v, keyable=0 ) pm.setAttr(aim_control.v, keyable=0 ) addToSet( [control, aim_control], 'controlsSet' ) pm.select( [control, aim_control], r=1 ) pm.color( ud=(CntlColors.left, CntlColors.right)[side] ) control.displayHandle.set(1) pm.select( control, r=1 ) pm.reorder( control.getShape(), back=1 ) return [ control, aim_control ]
def clusterObject(*args): pm.cluster()
def CreateIKFKSwitch(axis, Switch_CTRL, CTRL_list, visLine, wristJnt): clusterGRP = [] #create IK/FK Switch ctrl ========== Switch_Offset_GRP = str(Switch_CTRL) + '_offset_GRP' CreateStarCTRL(Switch_CTRL, CTRL_list, 0.5, [0.3, 0.3, 0.3], (0, 0, 1)) pm.addAttr(longName='IK_FK_Switch', at='double', defaultValue=0.0, minValue=0.0, maxValue=1) pm.setAttr(str(Switch_CTRL) + '.IK_FK_Switch', k=True) # move offset GRP to wrist jnt, remove const tempConst = pm.parentConstraint(wristJnt, str(Switch_CTRL), mo=False, sr=['x', 'y', 'z']) pm.delete(tempConst) pm.move(str(Switch_CTRL), (axis * 0.3, 0.6, -1), relative=True) CleanHist(Switch_CTRL) pm.xform(str(Switch_Offset_GRP), cp=True) # IK FK switch line ================ Switch_Line = pm.curve(n=visLine, d=1, p=[(0, 0, 0), (-1, 0, 0)], k=[0, 1]) curvePoints = cmds.ls('{0}.cv[:]'.format(Switch_Line), fl=True) wristPos = cmds.xform(str(wristJnt), query=True, translation=True, worldSpace=True) CTRL_Pos = cmds.xform(str(Switch_CTRL), query=True, translation=True, worldSpace=True) pm.move(curvePoints[1], wristPos) pm.move(curvePoints[0], ((axis * 5.07), 0.09, -0.6)) CleanHist(Switch_Line) pm.xform(str(Switch_Line), cp=True) # create clusters wristCluster = pm.cluster(curvePoints[1], n=(str(wristJnt) + '_IKFK_line_cluster')) CTRL_cluster = pm.cluster(curvePoints[0], n=(str(Switch_CTRL) + '_IKFK_line_cluster')) clusterGRP.extend([wristCluster, CTRL_cluster]) tempClusterConst = pm.parentConstraint(str(wristJnt), str(wristCluster[1]), mo=False, w=1) tempCtrlConst = pm.parentConstraint(str(wristJnt), str(Switch_Offset_GRP), mo=True, w=1) pm.parent(str(CTRL_cluster[1]), str(Switch_Offset_GRP)) CTRL_list.append(Switch_Offset_GRP) return clusterGRP
def CreateArm(WS_LOC, spaceGrps, rigging_GRP, ctrl_GRP, skeleton_GRP, vis_aid_GRP, jntList, IKJntList, FKJntList, CTRLs, prefix, jntRadius): side = 1 if prefix == 'R_': side = -1 # create simple arm jnts clavicle = pm.joint(n = str(prefix) + 'clavicle_jnt', p = (side * 0.4,0,0), rad = jntRadius) shoulder = pm.joint(n = str(prefix) + 'shoulder_jnt', p = (side * 1.3,0.3,0.4), rad = jntRadius) elbow = pm.joint(n = str(prefix) + 'elbow_jnt', p = (side * 3,0,0), rad = jntRadius) dist = Distance(shoulder,elbow) wrist = pm.joint(n = str(prefix) + 'wrist_jnt', p = ( side *(3 + dist),-0.3,0.4), rad = jntRadius) pm.parent(clavicle, world=True) # set jnt orientation pm.joint(clavicle, e=True, zso = True, oj='xyz', sao = 'yup') pm.joint(shoulder, e=True, zso = True, oj='xyz', sao = 'yup') pm.joint(elbow, e=True, zso = True, oj='xyz', sao = 'yup') pm.joint(wrist, e=True, zso = True, oj='none') # add jnts to list & create IK FK jnts jntList.extend([clavicle, shoulder, elbow, wrist]) #clavicle CTRL clavicleCtrl = str(prefix) + 'clavicle_CTRL' CreateCircleCTRL(str(clavicleCtrl), clavicle, (0,1,0), 0.8, (0,0,80)) CTRLs.append(str(clavicleCtrl) + '_offset_GRP') # create IK FK jnts IK_FKChain(jntList, IKJntList, FKJntList, CTRLs) IKJntList = IKJntList[::-1] FKJntList = FKJntList[::-1] # create hand handJntList = CreateHand(side, wrist, jntRadius) jntList.extend(handJntList) # create twist joints twistJntRadius = jntRadius + 0.1 #CreateTwistJnt(jntList, twistJntRadius, 'shoulder_twist_jnt', prefix, shoulder, 'none', False, True) #CreateTwistJnt(twistJntRadius, 'bicep_twist_jnt', prefix, shoulder, elbow, True, True) #CreateTwistJnt(twistJntRadius, 'elbow_upper_twist_jnt', prefix, elbow, shoulder, False, False) #CreateTwistJnt(twistJntRadius, 'elbow_twist_jnt', prefix, elbow, 'none', False, True) #CreateTwistJnt(twistJntRadius, 'radius_twist_jnt', prefix, elbow, wrist, True, True) #CreateTwistJnt(twistJntRadius, 'wrist_twist_jnt', prefix, wrist, elbow, False, False) # constrain jnts to IK and FK jnts shoulderConstr = pm.parentConstraint(FKJntList[0], IKJntList[0], str(shoulder), mo = False, w=1) elbowConstr = pm.parentConstraint(FKJntList[1], IKJntList[1], str(elbow), mo = False, w=1) wristConstr = pm.parentConstraint(FKJntList[2], IKJntList[2], str(wrist), mo = False, w=1) #create IK/FK Switch ctrl Switch_CTRL = str(prefix) + 'IK_FK_Switch_CTRL' Switch_Offset_GRP = str(Switch_CTRL) + '_offset_GRP' CreateStarCTRL(Switch_CTRL, 0.5, [0.3,0.3,0.3], (0,0,1)) pm.addAttr(longName='IK_FK_Switch', at = 'double', defaultValue=0.0, minValue=0.0, maxValue=1) pm.setAttr(str(Switch_CTRL) + '.IK_FK_Switch', k = True) # move offset GRP to wrist jnt, remove const tempConst = pm.parentConstraint(wrist, str(Switch_CTRL), mo = False, sr= ['x', 'y', 'z']) pm.delete(tempConst) pm.move(str(Switch_CTRL), (side * 0.3,0.6, -1 ), relative = True) CleanHist(Switch_CTRL) pm.xform(str(Switch_Offset_GRP), cp = True) # IK FK switch line Switch_Line = pm.curve(n = str(prefix) + 'IK_FK_VIS',d=1, p=[(0, 0, 0),(-1, 0, 0)], k=[0,1] ) curvePoints = cmds.ls('{0}.cv[:]'.format(Switch_Line), fl = True) wristPos = cmds.xform(str(wrist), query=True, translation=True, worldSpace=True ) CTRL_Pos = cmds.xform(str(Switch_CTRL), query=True, translation=True, worldSpace=True ) pm.move( curvePoints[1], wristPos) pm.move( curvePoints[0], ((side * 5.07),-0.11,-0.6)) CleanHist(Switch_Line) pm.xform(str(Switch_Line), cp = True) wristCluster = pm.cluster(curvePoints[1], n = (str(wrist) + '_IKFK_line_cluster')) CTRL_cluster = pm.cluster(curvePoints[0], n = (str(Switch_CTRL) + '_IKFK_line_cluster')) tempClusterConst = pm.parentConstraint(str(wrist), str(wristCluster[1]), mo = False, w = 1) tempCtrlConst = pm.parentConstraint(str(wrist), str(Switch_Offset_GRP), mo=True, w = 1) # connect IK FK with constraints revUtility = pm.shadingNode('reverse', n= str(prefix) + 'arm_IK_FK_reverse_node', asUtility=True) pm.connectAttr(str(Switch_CTRL) + '.IK_FK_Switch', str(revUtility) + '.inputX', force = True) ConnectIKFKConstr(revUtility, shoulderConstr, prefix, 'shoulder', Switch_CTRL) ConnectIKFKConstr(revUtility, elbowConstr, prefix, 'elbow', Switch_CTRL) ConnectIKFKConstr(revUtility, wristConstr, prefix, 'wrist', Switch_CTRL) pm.orientConstraint(str(prefix) + 'arm_IK_CTRL', IKJntList[2], mo = False) pm.connectAttr(str(Switch_CTRL) + '.IK_FK_Switch', str(prefix) + 'arm_IK_CTRL_offset_GRP.visibility', force = True) pm.connectAttr(str(Switch_CTRL) + '.IK_FK_Switch', str(prefix) + 'pole_vector_offset_GRP.visibility', force = True) pm.connectAttr(str(revUtility) + '.outputX', str(prefix) + 'shoulder_FK_CTRL_offset_GRP.visibility', force = True) # tidy up hierarchy pm.parent(Switch_Line, str(vis_aid_GRP)) pm.parent(str(CTRL_cluster[1]), str(Switch_Offset_GRP)) pm.parent(str(wristCluster[1]), str(ctrl_GRP)) pm.parent(CTRLs[0], ctrl_GRP) pm.parent(CTRLs[1], ctrl_GRP) pm.parent(CTRLs[2], ctrl_GRP) pm.parent(CTRLs[3], clavicleCtrl) IK_GRP = pm.group( em=True, name= str(prefix) + 'IK_GRP' ) pm.parent(str(IKJntList[0]) , IK_GRP) FK_GRP = pm.group( em=True, name= str(prefix) + 'FK_GRP' ) pm.parent(str(FKJntList[0]) , FK_GRP) arm_GRP = pm.group( em=True, name= str(prefix) + 'arm_GRP' ) pm.parent(FK_GRP, arm_GRP) pm.parent(IK_GRP, arm_GRP) CTRLs.append(str(Switch_CTRL) + '_offset_GRP') pm.parent(arm_GRP, rigging_GRP) pm.parent(jntList[0], skeleton_GRP) pm.parent(CTRLs[6], ctrl_GRP) pm.parentConstraint(clavicleCtrl,arm_GRP, mo = True, w = 1) """