def inColor(self, texture_attr):
cmds.connectAttr(texture_attr, self.attr('inColor'))
python类connectAttr()的实例源码
def connect(self, attr, nodes=None):
nodes = nodes or cmds.ls(sl=True)
if len(nodes) > len(self.get_uvs()):
raise Exception('More nodes than uv samples')
for i, node in enumerate(nodes):
color_attr = self.attr('outColor', i)
node_attr = node + '.' + attr
cmds.connectAttr(color_attr, node_attr, force=True)
def get_nucleus():
selection = cmds.ls(sl=True, dag=True, leaf=True, type='nucleus')
if selection:
return selection[0]
nucleus = cmds.ls(type='nucleus')
if nucleus:
return nucleus[0]
nucleus = cmds.createNode('nucleus')
cmds.connectAttr('time1.outTime', nucleus + '.currentTime')
return nucleus
def add_follicle(follicle_shape, hair_system):
hair_index = cmds.getAttr(hair_system + '.inputHair', size=True)
input_hair = '{}.inputHair[{}]'.format(hair_system, hair_index)
output_hair = '{}.outputHair[{}]'.format(hair_system, hair_index)
cmds.connectAttr(follicle_shape + '.outHair', input_hair)
cmds.connectAttr(output_hair, follicle_shape + '.currentPosition')
def createSpaceBuffers(*args):
"""
selection 1,2 = source parent, source obj
selection 3 = target obj
create two groups parented - named after source p,o
snap them to source obj
parentConstrain pGrp to sourceparent, oGrp to sourceobj
connectAttrs of oGrp to target obj(make sure values are zeroed)
"""
sel = cmds.ls(sl=True)
src1 = sel[0] # parent of Ctrl (or thing you want to relate it to)
src2 = sel[1] # ctrl
tgt = sel[2] # joint (should be in a group)
tgtGrp = cmds.group(em=True, name="{0}_spaceBuffer".format(src2))
tgtParGrp = cmds.group(em=True, name="{0}_spaceBuffer".format(src1))
cmds.parent(tgtGrp, tgtParGrp)
src1PC = cmds.parentConstraint(src1, tgtParGrp)
src2PC = cmds.parentConstraint(src2, tgtGrp)
if cmds.getAttr("{0}.t".format(tgt))[0]==(0,0,0):
cmds.connectAttr("{0}.t".format(src2), "{0}.t".format(tgt))
else:
print "{0} had non-zero translate values! Skipping connection.".format(tgt)
if cmds.getAttr("{0}.r".format(tgt))[0]==(0,0,0):
cmds.connectAttr("{0}.r".format(src2), "{0}.r".format(tgt))
else:
print "{0} had non-zero rotate values! Skipping connection.".format(tgt)
def createMessage(host="none", attr="none", target="none", *args):
"""creates a message attr on object with target as value. Args are: 'host'-some object to hold the message attr, 'attr'-the name of the message attribute to create, and 'target'-the host to be the value of the message attr"""
cmds.addAttr(host, at='message', ln=attr)
cmds.connectAttr("%s.message"%target, "%s.%s"%(host, attr))
return("%s.%s"%(host, attr))
def createAdd(name, input1, input2):
"""creates an addDoubleLinear node with name, object.attr, object.attr as args"""
adl = cmds.shadingNode("addDoubleLinear", asUtility=True, name=name)
cmds.connectAttr(input1, "%s.input1"%adl)
cmds.connectAttr(input2, "%s.input2"%adl)
return(adl)
def blendRotation(blend="none", sourceA="none", sourceB="none", target="none", sourceValue="none"):
#add input and *args?
"""name is first arg, then three objects. Blends rotation from first two selected into third selected. SourceValue (last input) is for the driving obj.attr. First source is active at '1', second at '2'"""
if blend == "none":
blend = "blendColors"
if sourceA == "none":
sel = getSelection()
if len(sel) != 3:
cmds.error("Error: blendRotation, select three transforms")
#inert some kind of break here
sourceA = sel[0]
sourceB = sel[1]
target = sel[2]
blend = cmds.shadingNode("blendColors", asUtility=True, name=blend)
sourceAOut = sourceA + ".rotate"
sourceBOut = sourceB + ".rotate"
targetIn = target + ".rotate"
blend1 = blend + ".color1"
blend2 = blend + ".color2"
blendOut = blend + ".output"
cmds.connectAttr(sourceAOut, blend1)
cmds.connectAttr(sourceBOut, blend2)
cmds.connectAttr(blendOut, targetIn)
if not sourceValue == "none":
cmds.connectAttr(sourceValue, "%s.blender"%blend)
return(blend)
def blendTranslate(blend="none", sourceA="none", sourceB="none", target="none", sourceValue="none"):
"""name is first arg, then three objects. Blends translation from first two selected into third selected. SourceValue (last input) is for the driving obj.attr. First source is active at '1', second at '2'"""
#add input and *args
if blend == "none":
blend = "blendColors"
if sourceA == "none":
sel = getSelection()
if len(sel) != 3:
cmds.error("Error: blendRotation, select three transforms")
#inert some kind of break here
sourceA = sel[0]
sourceB = sel[1]
target = sel[2]
blend = cmds.shadingNode("blendColors", asUtility=True, name=blend)
sourceAOut = sourceA + ".translate"
sourceBOut = sourceB + ".translate"
targetIn = target + ".translate"
blend1 = blend + ".color1"
blend2 = blend + ".color2"
blendOut = blend + ".output"
cmds.connectAttr(sourceAOut, blend1)
cmds.connectAttr(sourceBOut, blend2)
cmds.connectAttr(blendOut, targetIn)
if not sourceValue == "none":
cmds.connectAttr(sourceValue, "%s.blender"%blend)
return(blend)
def measureDistance(mName="none", *args):
"""first the name of the measure node, then the 2 objects ORRRR select the two objects and run (will give name 'distanceBetween'"""
objs = []
if mName == "none":
mName = "distanceBetween"
objs = getTwoSelection()
else:
for each in args:
objs.append(each)
#add check for 2 selectiont
if len(objs) != 2:
cmds.error("you must enter either a measure name and 2 objects OR no arguments and manually select 2 objs")
dist = cmds.shadingNode("distanceBetween", asUtility=True, name=mName)
objA = objs[0]
objB = objs[1]
objAMatrix = objA + ".worldMatrix"
objBMatrix = objB + ".worldMatrix"
objAPoint = objA + ".rotatePivot"
objBPoint = objB + ".rotatePivot"
distPoint1 = dist + ".point1"
distPoint2 = dist + ".point2"
distMatrix1 = dist + ".inMatrix1"
distMatrix2 = dist + ".inMatrix2"
cmds.connectAttr(objAPoint, distPoint1)
cmds.connectAttr(objBPoint, distPoint2)
cmds.connectAttr(objAMatrix, distMatrix1)
cmds.connectAttr(objBMatrix, distMatrix2)
cmds.select(clear=True)
return(dist)
def scaleStretchIK(limbName="none", ikTop="none", ikMid="none", ikLow="none", jntMeasure="none", IKMeasure="none", IKCtrl="none", axis="none", *args):
"""creates a stretch setup for 3 joint IK chain. Inputs (strings) are the limbName, 3 ik joints (top to bottom), the measure input for the whole chain (add up from measure joints), the measure for the ikCtrl, the ik handle or ctrl (which must have 'scaleMin', 'upScale' and 'lowScale' attrs, the axis letter. Returns . . . """
ratioMult = cmds.shadingNode("multiplyDivide", asUtility=True, n="%s_stretchRatioMult"%limbName)
cmds.setAttr(ratioMult + ".operation", 2)
cmds.connectAttr(jntMeasure, "%s.input2X"%ratioMult)
cmds.connectAttr(IKMeasure, "%s.input1X"%ratioMult)
#could put this default stuff (next two paragraphs) after the conditional and use another conditional so that minScale is bundled up in "autostretch"
#create default setting of 1 when autostretch is off
defaultMult = cmds.shadingNode("multiplyDivide", asUtility=True, n="%s_stretchDefaultMult"%limbName)
cmds.setAttr("%s.input1X"%defaultMult, 1)
#create blend node to blend ratio mult and default values, based on blender attr of ikctrl.autoStretch
defaultBlend = cmds.shadingNode("blendColors", asUtility=True, n="%s_stretchBlend"%limbName)
cmds.connectAttr("%s.outputX"%defaultMult, "%s.color2R"%defaultBlend)
cmds.connectAttr("%s.outputX"%ratioMult, "%s.color1R"%defaultBlend)
cmds.connectAttr("%s.autoStretch"%IKCtrl, "%s.blender"%defaultBlend)
#blend goes into condition node - firstTerm, secondTerm=ikctrl scaleMin value, operation=2(greaterthan), colorIfTrue is blend, colorIfFalse is scaleMin attr
conditional = cmds.shadingNode("condition", asUtility=True, n="%s_upStretchCondition"%limbName)
cmds.setAttr("%s.operation"%conditional, 2)
cmds.connectAttr("%s.outputR"%defaultBlend, "%s.firstTerm"%conditional)
cmds.connectAttr("%s.scaleMin"%IKCtrl, "%s.secondTerm"%conditional)
cmds.connectAttr("%s.outputR"%defaultBlend, "%s.colorIfTrueR"%conditional)
cmds.connectAttr("%s.scaleMin"%IKCtrl, "%s.colorIfFalseR"%conditional)
#factor in the upScale/lowScale attrs
upScaleMult = cmds.shadingNode('multiplyDivide', asUtility=True, n="%s_upScaleMult"%limbName)
cmds.connectAttr("%s.outColorR"%conditional, "%s.input1X"%upScaleMult)
cmds.connectAttr("%s.upScale"%IKCtrl, "%s.input2X"%upScaleMult)
loScaleMult = cmds.shadingNode('multiplyDivide', asUtility=True, n="%s_loScaleMult"%limbName)
cmds.connectAttr("%s.outColorR"%conditional, "%s.input1X"%loScaleMult)
cmds.connectAttr("%s.lowScale"%IKCtrl, "%s.input2X"%loScaleMult)
#hook up the scales of the joints
cmds.connectAttr("%s.outputX"%upScaleMult, "%s.s%s"%(ikTop, axis))
cmds.connectAttr("%s.outputX"%loScaleMult, "%s.s%s"%(ikMid, axis))
return(ratioMult, defaultMult, defaultBlend, conditional, upScaleMult, loScaleMult)
def zbw_mmChangeConnectAttr(base, attr, obj, *args):
#get that from the text field
newAttr = cmds.textFieldGrp("zbw_mmChangeAttrTFG", q=True, tx=True)
#delete old attr
cmds.deleteAttr(attr)
#create new attr
cmds.addAttr(base, at="message", ln=newAttr)
#create connection to obj in new attr
cmds.connectAttr((obj+".message"), (base+"."+newAttr), f=True)
#when you delete, then run the whole proc again afterwards (to clean up the nums)
cmds.deleteUI('zbw_mmChangeAttrUI', window=True)
cmds.windowPref('zbw_mmChangeAttrUI', remove=True)
cmds.deleteUI("mmRCListLayout")
zbw_mmListCurrentMessages("mmListMessages")
def zbw_mmChangeConnectObj(base, attr, obj, *args):
#get that from the text field
newObj = cmds.textFieldGrp("zbw_mmChangeObjTFBG", q=True, tx=True)
#create connection to obj in new attr
cmds.connectAttr((newObj+".message"), attr, f=True)
#delete this window, delete mmRCListLayout and call the list again
cmds.deleteUI('zbw_mmChangeObjUI', window=True)
cmds.windowPref('zbw_mmChangeObjUI', remove=True)
cmds.deleteUI("mmRCListLayout")
zbw_mmListCurrentMessages("mmListMessages")
def connectTexture(*args):
sel = cmds.ls(sl=True)
ctrl = sel[0]
# repeatMult = cmds.connectionInfo("{}.repeatMult".format(ctrl), sourceFromDestination=True).partition(".")[0]
# parameterMult = cmds.connectionInfo("{}.parameterMult".format(ctrl), sourceFromDestination=True).partition(".")[0]
# print repeatMult, parameterMult
if len(sel) > 1:
p2ds = sel[1:]
for node in p2ds:
cmds.connectAttr("{}.rptHolder".format(ctrl), "{}.repeatV".format(node))
def createWireDef(*args):
#clusterList = []
#rebuiltCrv = ""
#get geo and curve
geo = cmds.ls(sl=True)[0]
crv = cmds.ls(sl=True)[1]
rebuiltCrv = rebuildCrv(crv)
name = cmds.textFieldGrp(widgets["nameTFG"],q=True, tx=True)
defName = "wire_"+ name
wireDef = cmds.wire(geo, w = rebuiltCrv, n= defName, gw=True)
wireGroup = wireDef[1] + "Group"
cmds.setAttr(wireGroup + ".v", 0)
clusterList = clstrOnCurve(rebuiltCrv)
#print clusterList
ctrlGrp = createControls(clusterList)
masterGrp = cmds.group(n=name+"_GRP", em=True)
cmds.parent(ctrlGrp, masterGrp)
cmds.parent(wireGroup, masterGrp)
cmds.addAttr(masterGrp, ln="xxWireDeformerCtrlsXX", at="bool", k=True)
cmds.setAttr(masterGrp + ".xxWireDeformerCtrlsXX", l=True)
cmds.addAttr(masterGrp, ln = 'envelope', at = "float", dv = 1, min=0, max=1, k=True)
cmds.addAttr(masterGrp, ln = 'DropoffDistance', at = 'float', dv = 1, min = 0, max = 15, k = True)
cmds.addAttr(masterGrp, ln = 'tension', at = 'float', dv = 1, min = -10, max = 10, k = True)
cmds.addAttr(masterGrp, ln = 'rot', at = 'float', min = 0, max = 1, k =True)
cmds.addAttr(masterGrp, ln = 'scl', at = 'float', dv = 1, min = 0, max = 3, k = True)
cmds.connectAttr(masterGrp + ".envelope", wireDef[0] + ".envelope")
cmds.connectAttr(masterGrp + ".DropoffDistance", wireDef[0] + ".dropoffDistance[0]")
cmds.connectAttr(masterGrp + ".tension", wireDef[0] + ".tension")
cmds.connectAttr(masterGrp + ".rot", wireDef[0] + ".rotation")
cmds.connectAttr(masterGrp + ".scl", wireDef[0] + ".scale[0]")
cmds.select(masterGrp, r = True)
incrementName()
def transfer_attrs(*args):
"""
transfers attrs and connections from second obj to first object selected
"""
tgt, src = get_source_and_targets()
if not tgt or len(src) > 1:
cmds.warning("Select only one target then one source obj to transfer the attributes and connections!")
return ()
attrs = cmds.channelBox('mainChannelBox', q=True, selectedMainAttributes=True)
if not attrs:
cmds.warning("You have to select at least one attr on last object selected to transfer!")
return ()
for attr in attrs:
attrType, hasMin, attrMin, hasMax, attrMax, value, inConnection, outConnection, locked = get_channel_attributes(
src[0], attr)
if not attrType == "enum":
# create attribute
if not cmds.attributeQuery(attr, node=tgt, exists=True):
if hasMin and not hasMax:
cmds.addAttr(tgt, ln=attr, at=attrType, min=attrMin[0], dv=value, k=True)
elif hasMax and not hasMin:
cmds.addAttr(tgt, ln=attr, at=attrType, max=attrMax[0], dv=value, k=True)
elif hasMin and hasMax:
cmds.addAttr(tgt, ln=attr, at=attrType, min=attrMin[0], max=attrMax[0], dv=value, k=True)
else:
cmds.addAttr(tgt, ln=attr, at=attrType, dv=value, k=True)
else:
cmds.warning("The attribute: {0} already exists. Skipping creation!".format(attr))
# lock
if locked:
cmds.setAttr("{0}.{1}".format(tgt, attr), l=True)
else:
cmds.warning("I don't do enums at the moment!")
# connect tgt attr to connection, forced
if inConnection:
cmds.connectAttr(inConnection[0], "{0}.{1}".format(tgt, attr))
if outConnection:
for conn in outConnection:
cmds.connectAttr("{0}.{1}".format(tgt, attr), conn, force=True)
def connect_transform(driver, driven, source=WorldSpace, compensate=False):
"""Connect translation, rotation and scale via decomposeMatrix
Arguments:
driver (str): Absolute path to driver
driven (str): Absolute path to driven
source (str, optional): Either WorldSpace or LocalSpace,
default WorldSpace
compensate (bool, optional): Whether or not to take into account
the current transform, default False.
Returns:
output (list): Newly created nodes
"""
outputattr = ".matrix" if source == LocalSpace else ".worldMatrix[0]"
assert cmds.objExists(driver), "%s not found" % driver
assert cmds.objExists(driven), "%s not found" % driven
decompose = driver + "_decompose"
output = [decompose]
if not cmds.objExists(decompose):
decompose = cmds.createNode("decomposeMatrix", name=decompose)
if compensate:
multMatrix = cmds.createNode(
"multMatrix", name=driver + "_multMatrix")
# Compensate for drivens parentMatrix.
cmds.connectAttr(driver + outputattr,
multMatrix + ".matrixIn[0]")
cmds.connectAttr(driven + ".parentInverseMatrix",
multMatrix + ".matrixIn[1]")
cmds.connectAttr(multMatrix + ".matrixSum",
decompose + ".inputMatrix")
output.append(multMatrix)
else:
cmds.connectAttr(driver + outputattr,
decompose + ".inputMatrix")
# Drive driven with compensated driver.
cmds.connectAttr(decompose + ".outputTranslate", driven + ".t")
cmds.connectAttr(decompose + ".outputRotate", driven + ".r")
cmds.connectAttr(decompose + ".outputScale", driven + ".s")
return output
def clone(shape, worldspace=False):
"""Clone `shape`
Arguments:
shape (str): Absolute path to shape
worldspace (bool, optional): Whether or not to consider worldspace
Returns:
node (str): Newly created clone
"""
type = cmds.nodeType(shape)
assert type in ("mesh", "nurbsSurface", "nurbsCurve"), (
"clone() works on polygonal and nurbs surfaces")
src, dst = {
"mesh": (".outMesh", ".inMesh"),
"nurbsSurface": (".local", ".create"),
"nurbsCurve": (".local", ".create"),
}[type]
nodetype = cmds.nodeType(shape)
name = lib.unique(name=shape.rsplit("|")[-1])
clone = cmds.createNode(nodetype, name=name)
cmds.connectAttr(shape + src, clone + dst, force=True)
if worldspace:
transform = cmds.createNode("transformGeometry",
name=name + "_transformGeometry")
cmds.connectAttr(shape + src,
transform + ".inputGeometry", force=True)
cmds.connectAttr(shape + ".worldMatrix[0]",
transform + ".transform", force=True)
cmds.connectAttr(transform + ".outputGeometry",
clone + dst, force=True)
# Assign default shader
cmds.sets(clone, addElement="initialShadingGroup")
return clone
def follicle(*args):
supported = ["mesh", "nurbsSurface"]
selection = cmds.ls(sl=1)
new_follicles = []
for sel in selection:
uv = lib.uv_from_element(sel)
geometry_shape = lib.shape_from_element(sel)
geometry_transform = cmds.listRelatives(geometry_shape, parent=True)[0]
# Figure out output connection
inputs = [".inputMesh", ".inputSurface"]
outputs = [".outMesh", ".local"]
failed = False
type = cmds.nodeType(geometry_shape)
if type not in supported:
failed = True
shapes = cmds.listRelatives(geometry_shape, shapes=True)
if shapes:
geometry_shape = shapes[0]
type = cmds.nodeType(geometry_shape)
if type in supported:
failed = False
if failed:
cmds.error("Skipping '%s': Type not accepted" % type)
return
input = inputs[supported.index(type)]
output = outputs[supported.index(type)]
# Make follicle
follicle = cmds.createNode("follicle",
name=geometry_transform + "_follicleShape1")
follicle_transform = cmds.listRelatives(follicle, parent=True)[0]
follicle_transform = cmds.rename(follicle_transform,
geometry_transform + "_follicle1")
# Set U and V value
cmds.setAttr(follicle + ".parameterU", uv[0])
cmds.setAttr(follicle + ".parameterV", uv[1])
# Make the connections
cmds.connectAttr(follicle + ".outTranslate",
follicle_transform + ".translate")
cmds.connectAttr(follicle + ".outRotate",
follicle_transform + ".rotate")
cmds.connectAttr(geometry_shape + output,
follicle + input)
# Select last
new_follicles.append(follicle_transform)
# Select newly created follicles
if new_follicles:
cmds.select(new_follicles, r=1)
return new_follicles
def create_spine(start_joint, end_joint, lower_control, upper_control, name='spine'):
spline_chain, original_chain = shortcuts.duplicate_chain(start_joint, end_joint, prefix='ikSpine_')
# Create the spline ik
ikh, effector, curve = cmds.ikHandle(
name='{0}_ikh'.format(name), solver='ikSplineSolver',
startJoint=spline_chain[0], endEffector=spline_chain[-1], parentCurve=False,
simplifyCurve=False)
effector = cmds.rename(effector, '{0}_eff'.format(name))
curve = cmds.rename(curve, '{0}_crv'.format(name))
# Create the joints to skin the curve
curve_start_joint = cmds.duplicate(start_joint, parentOnly=True, name='{0}CurveStart_jnt'.format(name))
cmds.parent(curve_start_joint, lower_control)
curve_end_joint = cmds.duplicate(end_joint, parentOnly=True, name='{0}CurveEnd_jnt'.format(name))
cmds.parent(curve_end_joint, upper_control)
# Skin curve
cmds.skinCluster(curve_start_joint, curve_end_joint, curve, name='{0}_scl'.format(name), tsb=True)
# Create stretch network
curve_info = cmds.arclen(curve, constructionHistory=True)
mdn = cmds.createNode('multiplyDivide', name='{0}Stretch_mdn'.format(name))
cmds.connectAttr('{0}.arcLength'.format(curve_info), '{0}.input1X'.format(mdn))
cmds.setAttr('{0}.input2X'.format(mdn), cmds.getAttr('{0}.arcLength'.format(curve_info)))
cmds.setAttr('{0}.operation'.format(mdn), 2) # Divide
# Connect to joints
for joint in spline_chain[1:]:
tx = cmds.getAttr('{0}.translateX'.format(joint))
mdl = cmds.createNode('multDoubleLinear', name='{0}Stretch_mdl'.format(joint))
cmds.setAttr('{0}.input1'.format(mdl), tx)
cmds.connectAttr('{0}.outputX'.format(mdn), '{0}.input2'.format(mdl))
cmds.connectAttr('{0}.output'.format(mdl), '{0}.translateX'.format(joint))
# Setup advanced twist
cmds.setAttr('{0}.dTwistControlEnable'.format(ikh), True)
cmds.setAttr('{0}.dWorldUpType'.format(ikh), 4) # Object up
cmds.setAttr('{0}.dWorldUpAxis'.format(ikh), 0) # Positive Y Up
cmds.setAttr('{0}.dWorldUpVectorX'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorY'.format(ikh), 1)
cmds.setAttr('{0}.dWorldUpVectorZ'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorEndX'.format(ikh), 0)
cmds.setAttr('{0}.dWorldUpVectorEndY'.format(ikh), 1)
cmds.setAttr('{0}.dWorldUpVectorEndZ'.format(ikh), 0)
cmds.connectAttr('{0}.worldMatrix[0]'.format(lower_control), '{0}.dWorldUpMatrix'.format(ikh))
cmds.connectAttr('{0}.worldMatrix[0]'.format(upper_control), '{0}.dWorldUpMatrixEnd'.format(ikh))
# Constrain original chain back to spline chain
for ik_joint, joint in zip(spline_chain, original_chain):
if joint == end_joint:
cmds.pointConstraint(ik_joint, joint, mo=True)
cmds.orientConstraint(upper_control, joint, mo=True)
else:
cmds.parentConstraint(ik_joint, joint)